home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 31 / Amiga Format CD31 (1998-09-02)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1998-10].iso / -seriously_amiga- / sound / ahi / developer / paula / rcs / paula_audio.a,v < prev    next >
Text File  |  1998-07-16  |  151KB  |  7,402 lines

  1. head    4.20;
  2. access;
  3. symbols;
  4. locks
  5.     lcs:4.20; strict;
  6. comment    @-- @;
  7.  
  8.  
  9. 4.20
  10. date    98.06.28.09.26.04;    author lcs;    state Exp;
  11. branches;
  12. next    4.19;
  13.  
  14. 4.19
  15. date    98.02.16.02.38.15;    author lcs;    state Exp;
  16. branches;
  17. next    4.18;
  18.  
  19. 4.18
  20. date    98.02.09.00.41.36;    author lcs;    state Exp;
  21. branches;
  22. next    4.17;
  23.  
  24. 4.17
  25. date    98.01.10.19.47.33;    author lcs;    state Exp;
  26. branches;
  27. next    4.16;
  28.  
  29. 4.16
  30. date    97.12.02.09.28.28;    author lcs;    state Exp;
  31. branches;
  32. next    4.15;
  33.  
  34. 4.15
  35. date    97.12.02.09.27.33;    author lcs;    state Exp;
  36. branches;
  37. next    4.14;
  38.  
  39. 4.14
  40. date    97.12.02.09.26.03;    author lcs;    state Exp;
  41. branches;
  42. next    4.13;
  43.  
  44. 4.13
  45. date    97.12.02.09.24.16;    author lcs;    state Exp;
  46. branches;
  47. next    4.10;
  48.  
  49. 4.10
  50. date    97.12.02.09.22.37;    author lcs;    state Exp;
  51. branches;
  52. next    ;
  53.  
  54.  
  55. desc
  56. @AHI driver for Paula
  57. @
  58.  
  59.  
  60. 4.20
  61. log
  62. @The low pass filter state is now restored when the audio is deallocated.
  63. @
  64. text
  65. @*** ScR ***
  66.  
  67. * $Id: paula_audio.a,v 4.19 1998/02/16 02:38:15 lcs Exp lcs $
  68. * $Log: paula_audio.a,v $
  69. * Revision 4.19  1998/02/16 02:38:15  lcs
  70. * Recording didn't work in all modes!
  71. *
  72. * Revision 4.18  1998/02/09 00:41:36  lcs
  73. * Fixed a interrupt problem (playback could touch record's enable bits!).
  74. *
  75. * Revision 4.17  1998/01/10 19:47:33  lcs
  76. * Alright, the DMA version is ready for release.
  77. *
  78. * Revision 4.16  1997/12/02 09:28:28  lcs
  79. * Fixed all known problems in the DMA mode.
  80. *
  81. * Revision 4.15  1997/12/02 09:27:33  lcs
  82. * Added a DMA mode (beta).
  83. *
  84. * Revision 4.14  1997/12/02 09:26:03  lcs
  85. * Enclosed FindTask("Picasso96") with Forbid()/Permit(), in order to
  86. *     silence PatchWork.
  87. *
  88. * Revision 4.13  1997/12/02 09:24:16  lcs
  89. * Rewrote the conversion routines, they should be faster now?
  90. * Added the AHIpaulaBufferLength environment variable.
  91. * There were errors in the new conversion routines, when the tempo changed.
  92. * 8 bit modes now have hardware volume control.
  93. * Added the AHIpaulaSwapChannels environment variable.
  94. * AHIsub_GetAttr() is much faster now.
  95. *
  96. * Revision 4.10  1997/12/02 09:22:37  lcs
  97. * Initial RCS'ed version.
  98. *
  99.  
  100. *** NOTES ***
  101.  
  102. *  The sampler routines are just for fun. Since interrupts must not be disabled,
  103. * there are lots of clicks.
  104.  
  105. ;------------
  106.  
  107.     include    version.i
  108.  
  109. VSTRING    MACRO
  110.         VERS
  111.         dc.b    " ("
  112.         DATE
  113.         dc.b    ")",13,10,0
  114.     ENDM
  115. VERSTAG    MACRO
  116.         dc.b    0,"$VER: "
  117.         VERS
  118.         dc.b    " ("
  119.         DATE
  120.         dc.b    ")",0
  121.     ENDM
  122.  
  123.     incdir    include:
  124.  
  125.     include    hardware/all.i
  126.  
  127.     include    devices/audio.i
  128.     include    devices/timer.i
  129.     include    dos/dos.i
  130.     include    exec/exec.i
  131.     include    graphics/gfxbase.i
  132.     include intuition/intuitionbase.i
  133.     include intuition/screens.i
  134.     include    resources/misc.i
  135.     include    resources/card.i
  136.     include    utility/utility.i
  137.     include    utility/hooks.i
  138.  
  139.     include    lvo/cardres_lib.i
  140.     include    lvo/dos_lib.i
  141.     include    lvo/exec_lib.i
  142.     include    lvo/graphics_lib.i
  143.     include    lvo/intuition_lib.i
  144.     include    lvo/timer_lib.i
  145.     include    lvo/utility_lib.i
  146.  
  147.     include    devices/ahi.i
  148.     include    libraries/ahi_sub.i
  149.     include    lvo/ahi_sub_lib.i
  150.  
  151.     include    macros.i
  152.  
  153. DEBUG_DETAIL    SET    0
  154.  
  155. _ciaa        EQU    $bfe001
  156. _ciab        EQU    $bfd000
  157.  
  158. AUD0        EQU    $0A0
  159. AUD1        EQU    $0B0
  160. AUD2        EQU    $0C0
  161. AUD3        EQU    $0D0
  162. AUDLC        EQU    0
  163. AUDLEN        EQU    4
  164. AUDPER        EQU    6
  165. AUDVOL        EQU    8
  166. AUDPERVOL    EQU    6
  167.  
  168. INTF_AUDIO    EQU    INTF_AUD3|INTF_AUD2|INTF_AUD1|INTF_AUD0
  169.  
  170. PALFREQ        EQU    3546895
  171. NTSCFREQ    EQU    3579545
  172. MINPER        EQU    62
  173.  
  174.  
  175. DMABUFFSAMPLES    EQU    512    ; 8 of these will be allocated!
  176. RECORDSAMPLES    EQU    1024
  177.  
  178.  
  179. * paula.audio extra tags
  180. AHIDB_Paula14Bit    EQU    AHIDB_UserBase+0    * Boolean
  181. AHIDB_PaulaTable    EQU    AHIDB_UserBase+1    * Boolean
  182. AHIDB_PaulaDMA        EQU    AHIDB_UserBase+2    * Boolean
  183.  
  184.  * paulaBase (private)
  185.     STRUCTURE paulaBase,LIB_SIZE
  186.     UBYTE    pb_Flags
  187.     UBYTE    pb_Pad1
  188.     UWORD    pb_Pad2
  189.     APTR    pb_SysLib
  190.     ULONG    pb_SegList
  191.     APTR    pb_GfxLib
  192.     APTR    pb_UtilLib
  193.     APTR    pb_DosLib
  194.     APTR    pb_IntuiLib
  195.     APTR    pb_TimerLib
  196.     APTR    pb_MiscResource
  197.     APTR    pb_CardResource
  198.     LABEL    paulaBase_SIZEOF
  199.  
  200.  * channel (private) used in DMA mode
  201.  
  202.     STRUCTURE channel,0
  203.     UWORD    ch_IntMask            ;This channels interrupt bit
  204.     UWORD    ch_DMAMask            ;This channels DMA bit
  205.     UWORD    ch_Stereo            ;0 = Left, 1 = Right
  206.     UWORD    ch_DMALength
  207.     UBYTE    ch_EndOfSample            ;Flag
  208.     UBYTE    ch_NoInt            ;SetFreq() must not cause interrupt
  209.     UWORD    ch_Pad
  210.     APTR    ch_RegBase            ;This channels hardware register base
  211.  
  212.     ULONG    ch_Cleared            ;Samples already cleared
  213.     ULONG    ch_Cleared2            ;Samples already cleared
  214.  
  215.     ULONG    ch_Count            ;How mant samples played? (In samples)
  216.  
  217.     APTR    ch_Address            ;Current sample address
  218.     APTR    ch_NextAddress            ;Next sample address
  219.  
  220.     ULONG    ch_Offset            ;Where are we playing? (In samples)
  221.     ULONG    ch_NextOffset            ;Next...
  222.  
  223.     ULONG    ch_Length            ;Current sample length (In samples)
  224.     ULONG    ch_NextLength            ;Next sample length
  225.  
  226.     ULONG    ch_Type                ;Current sample type
  227.     ULONG    ch_NextType            ;Next sample type
  228.  
  229.     LABEL    ch_PerVol
  230.     UWORD    ch_Period            ;Current period (0 = stopped)
  231.     UWORD    ch_Volume            ;Current volume (scaled)
  232.     LABEL    ch_NextPerVol
  233.     UWORD    ch_NextPeriod            ;Next period
  234.     UWORD    ch_NextVolume            ;Next volume  (scaled)
  235.  
  236. ;    ULONG    ch_AudPerVol
  237.  
  238.     UWORD    ch_VolumeNorm
  239.     UWORD    ch_NextVolumeNorm
  240.  
  241.     UWORD    ch_Scale            ;Current frequency scale (2^ch_Scale)
  242.     UWORD    ch_NextScale            ;Next frequency scale
  243.  
  244.     STRUCT    ch_SndMsg,AHISoundMessage_SIZEOF
  245.  
  246.     LABEL    channel_SIZEOF
  247.  
  248.  * sound (private) used in DMA mode
  249.  
  250.     STRUCTURE sound,0
  251.     ULONG    so_Type
  252.     APTR    so_Address
  253.     ULONG    so_Length
  254.     LABEL    sound_SIZEOF
  255.  
  256.  * paula (private) ahiac_DriverData points to this structure.
  257.     STRUCTURE paula,0
  258.     UBYTE    p_Flags
  259.     UBYTE    p_Parallel            ;TRUE if parport allocated
  260.     UBYTE    p_Filter            ;TRUE if filter was on when alocating
  261.     UBYTE    p_Pad0
  262.     UWORD    p_DisableCount            ;AHIsub_Enable/AHIsub_Disable cnt
  263.     UWORD    p_IRQMask
  264.  
  265.     APTR    p_PaulaBase            ;Pointer to library base (DMA only)
  266.     APTR    p_AudioCtrl            ;Backpointer to AudioCtrl struct.
  267.  
  268.     ULONG    p_AudioFreq            ;PAL/NTSC clock constant
  269.     UWORD    p_SwapChannels            ;TRUE if left/right should be swapped
  270.     UWORD    p_ScreenIsDouble        ;TRUE if screen mode allows >28kHz
  271.     ULONG    p_MinBufferLength        ;Minimum length of chipmem playbuffer
  272.     APTR    p_CalibrationTable        ;Pointer to 14 bit conversion tables
  273.  
  274.     APTR    p_DMAbuffer            ;Chipmem play buffer
  275.     ULONG    p_DoubleBufferOffset        ;Buffer flag
  276.  
  277.     LABEL    p_AudPtrs            ; Pointers to chipmem play buffer
  278.     APTR    p_AudPtr1A
  279.     APTR    p_AudPtr2A
  280.     APTR    p_AudPtr3A
  281.     APTR    p_AudPtr4A
  282.     APTR    p_AudPtr1B
  283.     APTR    p_AudPtr2B
  284.     APTR    p_AudPtr3B
  285.     APTR    p_AudPtr4B
  286.  
  287.     APTR    p_audioport            ;For audio.device
  288.     APTR    p_audioreq            ;For audio.device
  289.     ULONG    p_audiodev            ;For audio.device
  290.     APTR    p_ParBitsUser            ;Parallel port locking
  291.     APTR    p_ParPortUser            ;Parallel port locking
  292.     APTR    p_SerBitsUser            ;Serial port locking
  293.     APTR    p_CardHandle            ;Aura PCMCIA card hanle
  294.  
  295.     STRUCT    p_PlayInt,IS_SIZE        ;Player hardware interrupt
  296.     STRUCT    p_PlaySoftInt,IS_SIZE        ;Player software interrupt (mixing only)
  297.     STRUCT    p_RecInt,IS_SIZE        ;Recorder hardware interrupt (mixing only)
  298.     STRUCT    p_RecSoftInt,IS_SIZE        ;Recorder software interrupt (mixing only)
  299.  
  300.     UWORD    p_AudPer            ;Playback period (mixing only)
  301.     UWORD    p_OutputVolume            ;Hardware volume (mixing only)
  302.     UWORD    p_MonitorVolume            ;Monitor volume (mixing only)
  303.     UWORD    p_Input                ;Input select (mixing only)
  304.  
  305.     ULONG    p_LoopTimes            ;(mixing only)
  306.  
  307.     LABEL    p_PlayerHookRegs        ;PlayerHook
  308.     APTR    p_PlayerHook
  309.     ULONG    p_Reserved
  310.     FPTR    p_PlayerEntry            ;p_PlayerHook->h_Entry
  311.  
  312.     LABEL    p_MixHookRegs            ;MixingHook (mixing only)
  313.     APTR    p_MixHook
  314.     APTR    p_Mixbuffer
  315.     FPTR    p_MixEntry            ;p_MixHook->h_Entry
  316.  
  317.     LABEL    p_RecIntDataAura        ;Record data structure for Aura sampl.
  318.     APTR    p_AuraAddress            ;DO NOT CHANGE ORDER!
  319.     LABEL    p_RecIntData            ;Record data structure
  320.     APTR    p_RecFillPtr
  321.     UWORD    p_RecFillCount
  322.     UWORD    p_Pad2
  323.     APTR    p_RecBuffer1
  324.     APTR    p_RecBuffer2
  325.     APTR    p_RecSoftIntPtr
  326.  
  327.     LABEL    p_RecordMessage            ;Message used with SamplerFunc()
  328.     ULONG    p_rmType
  329.     APTR    p_rmBuffer
  330.     ULONG    p_rmLength
  331.  
  332.     ULONG    p_EClock            ;System E clock freq. (DMA only)
  333.     ULONG    p_EPeriod            ;PlayerFunc() E clk period (DMA only)
  334.     STRUCT    p_EAlarm,EV_SIZE        ;E Clock to wait for (DMA only)
  335.     STRUCT    p_TimerPort,MP_SIZE        ;(DMA only)
  336.     STRUCT    p_TimerInt,IS_SIZE        ;(DMA only)
  337.     APTR    p_TimerReq            ;Used to drive PlayerFunc() (DMA only)
  338.     UBYTE    p_TimerDev            ;(DMA only)
  339.     UBYTE    p_TimerPad
  340.     UWORD    p_TimerCommFlag            ;Used to end timer (DMA only)
  341.  
  342.     ULONG    p_MasterVolume            ;Effect parameter (DMA only)
  343.     APTR    p_ChannelInfo            ;Effect structure (DMA only)
  344.  
  345.     APTR    p_Sounds
  346.     STRUCT    p_Channels,channel_SIZEOF*4    ;DMA playback channel info
  347.  
  348.     STRUCT    p_CalibrationArray,256        ;14 bit calibration prefs
  349.  
  350.     LABEL    paula_SIZEOF
  351.  
  352. * p_Flags
  353.     BITDEF    P,14BIT,0
  354.     BITDEF    P,HIFI,1
  355. PB_STEREO    EQU    AHIACB_STEREO        ;=2
  356. PF_STEREO    EQU    AHIACF_STEREO
  357.     BITDEF    P,DMA,3
  358.  
  359. Start:
  360.     moveq    #-1,d0
  361.     rts
  362.  
  363. RomTag:
  364.     DC.W    RTC_MATCHWORD
  365.     DC.L    RomTag
  366.     DC.L    EndCode
  367.     DC.B    RTF_AUTOINIT
  368.     DC.B    VERSION                ;version
  369.     DC.B    NT_LIBRARY
  370.     DC.B    0                ;pri
  371.     DC.L    LibName
  372.     DC.L    IDString
  373.     DC.L    InitTable
  374.  
  375. LibName:    dc.b    "paula.audio",0
  376. IDString:    VSTRING
  377. gfxName:    GRAPHICSNAME
  378. utilName:    UTILITYNAME
  379. dosName:    DOSNAME
  380. intuiName:    dc.b    "intuition.library",0
  381. timerName:    dc.b    "timer.device",0
  382. miscName:    MISCNAME
  383. cardName:    dc.b    "card.resource",0
  384. filterVar:    dc.b    "AHIpaulaFilterFreq",0
  385. screenVar:    dc.b    "AHIpaulaSampleLimit",0
  386. bufferVar:    dc.b    "AHIpaulaBufferLength",0
  387. swapVar:    dc.b    "AHIpaulaSwapChannels",0
  388.     cnop    0,2
  389.  
  390. InitTable:
  391.     DC.L    paulaBase_SIZEOF
  392.     DC.L    funcTable
  393.     DC.L    dataTable
  394.     DC.L    initRoutine
  395.  
  396. funcTable:
  397.     dc.l    Open
  398.     dc.l    Close
  399.     dc.l    Expunge
  400.     dc.l    Null
  401. *
  402.     dc.l    AHIsub_AllocAudio
  403.     dc.l    AHIsub_FreeAudio
  404.     dc.l    AHIsub_Disable
  405.     dc.l    AHIsub_Enable
  406.     dc.l    AHIsub_Start
  407.     dc.l    AHIsub_Update
  408.     dc.l    AHIsub_Stop
  409.     dc.l    AHIsub_SetVol
  410.     dc.l    AHIsub_SetFreq
  411.     dc.l    AHIsub_SetSound
  412.     dc.l    AHIsub_SetEffect
  413.     dc.l    AHIsub_LoadSound
  414.     dc.l    AHIsub_UnloadSound
  415.     dc.l    AHIsub_GetAttr
  416.     dc.l    AHIsub_HardwareControl
  417.     dc.l    -1
  418.  
  419. dataTable:
  420.     INITBYTE    LN_TYPE,NT_LIBRARY
  421.     INITLONG    LN_NAME,LibName
  422.     INITBYTE    LIB_FLAGS,LIBF_SUMUSED|LIBF_CHANGED
  423.     INITWORD    LIB_VERSION,VERSION
  424.     INITWORD    LIB_REVISION,REVISION
  425.     INITLONG    LIB_IDSTRING,IDString
  426.     DC.L        0
  427.  
  428. initRoutine:
  429.     movem.l    d1/a0/a1/a5/a6,-(sp)
  430.     move.l    d0,a5
  431.     move.l    a6,pb_SysLib(a5)
  432.     move.l    a0,pb_SegList(a5)
  433.     lea    gfxName(pc),a1
  434.     moveq    #0,d0
  435.     call    OpenLibrary
  436.     move.l    d0,pb_GfxLib(a5)
  437.     bne.b    .gfxOK
  438.     ALERT    AG_OpenLib|AO_GraphicsLib
  439.     moveq    #0,d0
  440.     bra    .exit
  441. .gfxOK
  442.     lea    utilName(pc),a1
  443.     moveq    #0,d0
  444.     call    OpenLibrary
  445.     move.l    d0,pb_UtilLib(a5)
  446.     bne.b    .utilOK
  447.     ALERT    AG_OpenLib|AO_UtilityLib
  448.     moveq    #0,d0
  449.     bra    .exit
  450. .utilOK
  451.     lea    dosName(pc),a1
  452.     moveq    #0,d0
  453.     call    OpenLibrary
  454.     move.l    d0,pb_DosLib(a5)
  455.     bne.b    .dosOK
  456.     ALERT    AG_OpenLib|AO_DOSLib
  457.     moveq    #0,d0
  458.     bra    .exit
  459. .dosOK
  460.     lea    intuiName(pc),a1
  461.     moveq    #0,d0
  462.     call    OpenLibrary
  463.     move.l    d0,pb_IntuiLib(a5)
  464.     bne.b    .intuiOK
  465.     ALERT    AG_OpenLib|AO_Intuition
  466.     moveq    #0,d0
  467.     bra    .exit
  468. .intuiOK
  469.     lea    miscName(pc),a1
  470.     call    OpenResource
  471.     move.l    d0,pb_MiscResource(a5)
  472.     bne.b    .miscOK
  473.     ALERT    AG_OpenRes|AO_MiscRsrc
  474.     moveq    #0,d0
  475.     bra    .exit
  476. .miscOK
  477.     lea    cardName(pc),a1
  478.     call    OpenResource
  479.     move.l    d0,pb_CardResource(a5)        ;Don't fail on error
  480.  
  481.     move.l    a5,d0
  482. .exit
  483.     movem.l    (sp)+,d1/a0/a1/a5/a6
  484.     rts
  485.  
  486. Open:
  487.     moveq    #0,d0
  488.     addq.w    #1,LIB_OPENCNT(a6)
  489.     bclr.b    #LIBB_DELEXP,pb_Flags(a6)
  490.     move.l    a6,d0
  491. .exit
  492.     rts
  493.  
  494. Close:
  495.     moveq    #0,d0
  496.     subq.w    #1,LIB_OPENCNT(a6)
  497.     bne.b    .exit
  498.     btst.b    #LIBB_DELEXP,pb_Flags(a6)
  499.     beq.b    .exit
  500.     bsr    Expunge
  501. .exit
  502.     rts
  503.  
  504. Expunge:
  505.     movem.l    d1/d2/a0/a1/a5/a6,-(sp)
  506.     move.l    a6,a5
  507.     move.l    pb_SysLib(a5),a6
  508.     tst.w    LIB_OPENCNT(a5)
  509.     beq.b    .notopen
  510.     bset.b    #LIBB_DELEXP,pb_Flags(a5)
  511.     moveq    #0,d0
  512.     bra.b    .Expunge_end
  513. .notopen
  514.     move.l    pb_IntuiLib(a5),a1
  515.     call    CloseLibrary
  516.  
  517.     move.l    pb_DosLib(a5),a1
  518.     call    CloseLibrary
  519.  
  520.     move.l    pb_UtilLib(a5),a1
  521.     call    CloseLibrary
  522.  
  523.     move.l    pb_GfxLib(a5),a1
  524.     call    CloseLibrary
  525.  
  526.     move.l    pb_SegList(a5),d2
  527.     move.l    a5,a1
  528.     call    Remove
  529.  
  530.     moveq    #0,d0
  531.     move.l    a5,a1
  532.     move.w    LIB_NEGSIZE(a5),d0
  533.     sub.l    d0,a1
  534.     add.w    LIB_POSSIZE(a5),d0
  535.     call    FreeMem
  536.     move.l    d2,d0
  537. .Expunge_end
  538.     movem.l    (sp)+,d1/d2/a0/a1/a5/a6
  539.     rts
  540.  
  541. Null:
  542.     moveq    #0,d0
  543.     rts
  544.  
  545. * BeginIO(ioRequest)(a1) (From amiga.lib)
  546. BeginIO:
  547.     move.l    a1,a0        ;probably not neccesary
  548.     push    a6
  549.     move.l    IO_DEVICE(a1),a6
  550.     jsr    -30(a6)
  551.     pop    a6
  552.     rts
  553.  
  554.  
  555. ****** [driver].audio/--background-- ****************************************
  556. *
  557. *   OVERVIEW
  558. *
  559. *       GENERAL PROGRAMMING GUIDLINES
  560. *
  561. *       The driver must be able to be OpenLibrary()'ed even if the
  562. *       hardware is not present. If a library the driver uses fails
  563. *       to open, it is ok to fail at the library init routine, but please
  564. *       avoid it if possible.
  565. *
  566. *       Please note that this document could be much better, but since not
  567. *       many will ever need to read it, it will probably stay this way.
  568. *       Don't hesitate to contact Martin Blom when you're writing a driver!
  569. *
  570. *       DRIVER VERSIONS
  571. *
  572. *       The lowest supported driver version is 2. If you use any feature
  573. *       introduced in later versions of AHI, you should set the driver
  574. *       version to the same version as the features were introduced with.
  575. *       Example: You use PreTimer() and PostTimer(), and since these
  576. *       calls were added in V4 of ahi.device, your driver's version should
  577. *       be 4, too.
  578. *
  579. *       AUDIO ID NUMBERS
  580. *
  581. *       Just some notes about selecting ID numbers for different modes:
  582. *       It is up to the driver programmer to chose which modes should be
  583. *       available to the user. Take care when selecting.
  584. *
  585. *       The upper word is the hardware ID, and can only be allocated by
  586. *       Martin Blom <lcs@@lysator.liu.se>. The lower word is free, but in
  587. *       order to allow enhancements, please only use bit 0 to 4 for modes!
  588. *       If your driver supports multiple sound cards, use bit 12-15 to
  589. *       select card (first one is 0). If your sound card has multiple
  590. *       AD/DA converters, you can use bit 8-11 to select them (the first
  591. *       should be 0).
  592. *
  593. *       Set the remaining bits to zero.
  594. *
  595. *       Use AHI:Developer/Support/ScanAudioModes to have a look at the modes
  596. *       currently available. Use AHI:Developer/Support/sift to make sure your
  597. *       mode descriptor file is a legal IFF file.
  598. *
  599. *       I do reserve the right to change the rules if I find them incorrect!
  600. *
  601. *****************************************************************************
  602. *
  603. *
  604.  
  605.  
  606. ****** [driver].audio/AHIsub_AllocAudio *************************************
  607. *
  608. *   NAME
  609. *       AHIsub_AllocAudio -- Allocates and initializes the audio hardware.
  610. *
  611. *   SYNOPSIS
  612. *       result = AHIsub_AllocAudio( tags, audioctrl);
  613. *       D0                          A1    A2
  614. *
  615. *       ULONG AHIsub_AllocAudio( struct TagItem *, struct AHIAudioCtrlDrv * );
  616. *
  617. *   IMPLEMENTATION
  618. *       Allocate and initialize the audio hardware. Decide if and how you
  619. *       wish to use the mixing routines provided by 'ahi.device', by looking
  620. *       in the AHIAudioCtrlDrv structure and parsing the tag list for tags
  621. *       you support.
  622. *
  623. *       1) Use mixing routines with timing:
  624. *           You will need to be able to play any number of samples from
  625. *           about 80 up to 65535 with low overhead.
  626. *           · Update AudioCtrl->ahiac_MixFreq to nearest value that your
  627. *             hardware supports.
  628. *           · Return AHISF_MIXING|AHISF_TIMING.
  629. *
  630. *       2) Use mixing routines without timing:
  631. *           If the hardware can't play samples with any length, use this
  632. *           alternative and provide timing yourself. The buffer must
  633. *           take less than about 20 ms to play, preferable less than 10!
  634. *           · Update AudioCtrl->ahiac_MixFreq to nearest value that your
  635. *             hardware supports.
  636. *           · Store the number of samples to mix each pass in
  637. *             AudioCtrl->ahiac_BuffSamples.
  638. *           · Return AHISF_MIXING
  639. *           Alternatively, you can use the first method and call the
  640. *           mixing hook several times in a row to fill up a buffer.
  641. *           In that case, AHIsub_GetAttr(AHIDB_MaxPlaySamples) should
  642. *           return the size of the buffer plus AudioCtrl->ahiac_MaxBuffSamples.
  643. *           If the buffer is so large that it takes more than (approx.) 10 ms to
  644. *           play it for high sample frequencies, AHIsub_GetAttr(AHIDB_Realtime)
  645. *           should return FALSE.
  646. *
  647. *       3) Don't use mixing routines:
  648. *           If your hardware can handle everything without using the CPU to
  649. *           mix the channels, you tell 'ahi.device' this by not setting
  650. *           either the AHISB_MIXING or the AHISB_TIMING bit.
  651. *
  652. *       If you can handle stereo output from the mixing routines, also set
  653. *       bit AHISB_KNOWSTEREO.
  654. *
  655. *       If you can handle hifi (32 bit) output from the mixing routines,
  656. *       set bit AHISB_KNOWHIFI.
  657. *
  658. *       If this driver can be used to record samples, set bit AHISB_CANRECORD,
  659. *       too (regardless if you use the mixing routines in AHI or not).
  660. *
  661. *       If the sound card has hardware to do DSP effects, you can set the
  662. *       AHISB_CANPOSTPROCESS bit. The output from the mixing routines will 
  663. *       then be two separate buffers, one wet and one dry. You should then
  664. *       apply the Fx on the wet buffer, and post-mix the two buffers before
  665. *       you send the samples to the DAC. (V4)
  666. *
  667. *   INPUTS
  668. *       tags - pointer to a taglist.
  669. *       audioctrl - pointer to an AHIAudioCtrlDrv structure.
  670. *
  671. *   TAGS
  672. *       The tags are from the audio database (AHIDB_#? in <devices/ahi.h>),
  673. *       NOT the tag list the user called ahi.device/AHI_AllocAudio() with.
  674. *
  675. *   RESULT
  676. *       Flags, defined in <libraries/ahi_sub.h>.
  677. *
  678. *   EXAMPLE
  679. *
  680. *   NOTES
  681. *       You don't have to clean up on failure, AHIsub_FreeAudio() will
  682. *       always be called.
  683. *
  684. *   BUGS
  685. *
  686. *   SEE ALSO
  687. *       AHIsub_FreeAudio(), AHIsub_Start()
  688. *
  689. *****************************************************************************
  690. *
  691. *
  692.  
  693. AHIsub_AllocAudio:
  694.     PRINTF    2,"H"
  695.     PRINTF    2,"AHIsub_AllocAudio()"
  696.  
  697.     pushm    std
  698.     move.l    a6,a5
  699.  
  700.     move.l    a1,d3
  701.  
  702.  
  703. * Allocate the 'paula' structure (our variables)
  704.     move.l    pb_SysLib(a5),a6
  705.     move.l    #paula_SIZEOF,d0
  706.     move.l    #MEMF_PUBLIC|MEMF_CLEAR,d1
  707.     call    AllocVec
  708.     move.l    d0,ahiac_DriverData(a2)
  709.     beq    .error_nopaula
  710.     move.l    d0,a3
  711.  
  712. * Initialize some fields...
  713.     move.b    #-1,p_TimerDev(a3)
  714.     move.l    #-1,p_audiodev(a3)
  715.     move.l    #-1,p_ParBitsUser(a3)
  716.     move.l    #-1,p_ParPortUser(a3)
  717.     move.l    #-1,p_SerBitsUser(a3)
  718.     move.l    a5,p_PaulaBase(a3)
  719.     move.l    a2,p_AudioCtrl(a3)
  720.     lea    p_RecSoftInt(a3),a0
  721.     move.l    a0,p_RecSoftIntPtr(a3)
  722.     move.l    #AHIST_S16S,p_rmType(a3)
  723.     move.l    #RECORDSAMPLES,p_rmLength(a3)
  724.     move.w    #64,p_OutputVolume(a3)
  725.     move.l    #$10000,p_MasterVolume(a3)
  726.  
  727. * Translate tags to flags
  728.     move.l    pb_UtilLib(a5),a6
  729.  
  730.     move.l    ahiac_Flags(a2),d2
  731.     and.b    #PF_STEREO,d2            ;same as AHIACF_STEREO
  732.  
  733.     move.l    #AHIDB_Paula14Bit,d0
  734.     moveq    #FALSE,d1
  735.     move.l    d3,a0                ;tag list
  736.     call    GetTagData
  737.     tst.l    d0
  738.     beq.b    .no14bit
  739.     or.b    #PF_14BIT,d2
  740. .no14bit
  741.     move.l    #AHIDB_HiFi,d0
  742.     moveq    #FALSE,d1
  743.     move.l    d3,a0                ;tag list
  744.     call    GetTagData
  745.     tst.l    d0
  746.     beq.b    .noHiFi
  747.     or.b    #PF_HIFI,d2
  748. .noHiFi
  749.     move.l    #AHIDB_PaulaDMA,d0
  750.     moveq    #FALSE,d1
  751.     move.l    d3,a0                ;tag list
  752.     call    GetTagData
  753.     tst.l    d0
  754.     beq.b    .noDMA
  755.     or.b    #PF_DMA,d2
  756. .noDMA
  757.  
  758.     move.b    p_Flags(a3),d1
  759.     and.b    #~(PF_STEREO|PF_14BIT|PF_HIFI|PF_DMA),d1
  760.     or.b    d2,d1
  761.     move.b    d1,p_Flags(a3)
  762.  
  763.     move.l    #PALFREQ,d2            ;PAL
  764.     move.l    pb_GfxLib(a5),a0
  765.     move.w    gb_DisplayFlags(a0),d0
  766.     btst    #REALLY_PALn,d0
  767.     bne.b    .1
  768.     move.l    #NTSCFREQ,d2            ;NTSC
  769. .1
  770.     move.l    d2,p_AudioFreq(a3)
  771.     bsr    checkvideo
  772.     move.w    d0,p_ScreenIsDouble(a3)
  773.  
  774. * Check if a table should be used (14 bit calibration)
  775.     move.l    #AHIDB_PaulaTable,d0
  776.     moveq    #0,d1
  777.     move.l    d3,a0                ;tag list
  778.     call    GetTagData
  779.     tst.l    d0
  780.     beq    .notable
  781.  
  782. * Load 'ENV:CyberSound/SoundDrivers/14Bit_Calibration', allocate
  783. * and initialize the table.
  784. * FIXIT: The calibration file should move to a special chunk in
  785. * 'DEVS:AudioModes/PAULA'.
  786.     move.l    pb_DosLib(a5),a6
  787.     lea    .calibname(pc),a0
  788.     move.l    a0,d1
  789.     move.l    #MODE_OLDFILE,d2
  790.     call    Open
  791.     move.l    d0,d4
  792.     beq    .nocalib
  793.     move.l    d0,d1
  794.     lea    p_CalibrationArray(a3),a0
  795.     move.l    a0,d2
  796.     move.l    #256,d3
  797.     call    Read
  798.     cmp.l    d0,d3
  799.     beq    .tableloaded
  800. .nocalib
  801. ; Fill defaults
  802.     lea    p_CalibrationArray(a3),a0
  803.     move.w    #254-1,d0
  804. .initcalib
  805.     move.b    #$55,(a0)+
  806.     dbf    d0,.initcalib
  807.     move.b    #$7f,(a0)+
  808. .tableloaded
  809.     move.l    d4,d1
  810.     beq.b    .nofile
  811.     call    Close
  812. .nofile
  813.     move.l    pb_SysLib(a5),a6
  814.     move.l    #65536*2,d0
  815.     move.l    #MEMF_PUBLIC,d1
  816.     call    AllocVec
  817.     move.l    d0,p_CalibrationTable(a3)
  818.     beq.b    .notable
  819.     move.l    d0,a0            ;table
  820.     lea    p_CalibrationArray(a3),a1
  821.     bsr.w    _CreateTable
  822. .notable
  823.  
  824. * Get the minimum chip buffer size
  825.     moveq    #0,d5                ;Default
  826.     move.l    pb_DosLib(a5),a6
  827.     subq.l    #8,sp                ;local label
  828.     move.w    #("0"<<8)|0,(sp)        ;Initialize as "0"
  829.     lea    bufferVar(pc),a0
  830.     move.l    a0,d1
  831.     move.l    sp,d2
  832.     moveq.l    #8,d3
  833.     moveq.l    #0,d4
  834.     call    GetVar
  835.     cmp.l    #-1,d0
  836.     beq    .gotlength
  837.     move.l    sp,d1
  838.     pea.l    0.w
  839.     move.l    sp,d2
  840.     call    StrToLong
  841.     move.l    (sp)+,d5
  842. .gotlength
  843.     addq.l    #8,sp
  844. ; d5 is now the buffer length
  845.     move.l    d5,p_MinBufferLength(a3)
  846.  
  847. * Check if we should swap left & right channels
  848.     moveq    #0,d5                ;Default
  849.     move.l    pb_DosLib(a5),a6
  850.     subq.l    #8,sp                ;local label
  851.     move.w    #("0"<<8)|0,(sp)        ;Initialize as "0"
  852.     lea    swapVar(pc),a0
  853.     move.l    a0,d1
  854.     move.l    sp,d2
  855.     moveq.l    #8,d3
  856.     moveq.l    #0,d4
  857.     call    GetVar
  858.     cmp.l    #-1,d0
  859.     beq    .gotswap
  860.     move.l    sp,d1
  861.     pea.l    0.w
  862.     move.l    sp,d2
  863.     call    StrToLong
  864.     move.l    (sp)+,d5
  865. .gotswap
  866.     addq.l    #8,sp
  867. ; d5 is now the buffer length
  868.     move.w    d5,p_SwapChannels(a3)
  869.  
  870. * allocate audio.device
  871.     move.l    pb_SysLib(a5),a6
  872.     call    CreateMsgPort
  873.     move.l    d0,p_audioport(a3)
  874.     beq    .error_noport
  875.     moveq    #ioa_SIZEOF,d0
  876.     move.l    #MEMF_PUBLIC|MEMF_CLEAR,d1
  877.     call    AllocVec
  878.     move.l    d0,p_audioreq(a3)
  879.     beq    .error_noreqmem
  880.     move.l    d0,a0
  881.     move.l    p_audioport(a3),MN_REPLYPORT(a0)
  882.     clr.w    ioa_AllocKey(a0)
  883.     move.b    #127,LN_PRI(a0)            ;steal it!
  884.     lea    .audiochannelarray(pc),a1
  885.     move.l    a1,ioa_Data(a0)
  886.     move.l    #1,ioa_Length(a0)
  887.     lea    .audioname(pc),a0
  888.     moveq    #0,d0
  889.     move.l    p_audioreq(a3),a1
  890.     moveq    #0,d1
  891.     call    OpenDevice
  892.     move.l    d0,p_audiodev(a3)
  893.     bne    .error_noaudiodev        ;somebody already owns the hardware (could be us!)
  894.     move.l    p_audioreq(a3),a1
  895.     move.w    #CMD_RESET,IO_COMMAND(a1)
  896.     bsr.w    BeginIO                ;clear attach, stop sound.
  897.     move.l    p_audioport(a3),a0
  898.     call    WaitPort
  899.     move.l    p_audioport(a3),a0
  900.     call    GetMsg
  901.  
  902.     move.l    pb_DosLib(a5),a6
  903.     moveq    #1,d1
  904.     call    Delay
  905.  
  906. * Set dummy interrupt handler
  907.     move.l    pb_SysLib(a5),a6
  908.     move.l    #Interrupt_Dummy,IS_CODE+p_PlayInt(a3)
  909.  
  910.     lea    p_PlayInt(a3),a1
  911.     moveq    #INTB_AUD0,d0
  912.     call    SetIntVector
  913.     lea    p_PlayInt(a3),a1
  914.     moveq    #INTB_AUD1,d0
  915.     call    SetIntVector
  916.     lea    p_PlayInt(a3),a1
  917.     moveq    #INTB_AUD2,d0
  918.     call    SetIntVector
  919.     lea    p_PlayInt(a3),a1
  920.     moveq    #INTB_AUD3,d0
  921.     call    SetIntVector
  922.  
  923. * test if mode supports recording
  924.     move.b    p_Flags(a3),d0
  925.     and.b    #PF_14BIT|PF_DMA,d0
  926.     bne    .dontgetsampler            ;no record if 14 bit and DMA modes
  927.  
  928. * try to allocate parallel port
  929.     clr.b    p_Parallel(a3)
  930.     move.l    pb_MiscResource(a5),a6
  931.     moveq    #MR_PARALLELBITS,d0
  932.     lea    IDString(pc),a1
  933.     jsr    MR_ALLOCMISCRESOURCE(a6)
  934.     move.l    d0,p_ParBitsUser(a3)
  935.     bne    .no_parrallel
  936.     moveq    #MR_PARALLELPORT,d0
  937.     lea    IDString(pc),a1
  938.     jsr    MR_ALLOCMISCRESOURCE(a6)
  939.     move.l    d0,p_ParPortUser(a3)
  940.     bne    .no_parrallel
  941.  
  942.     move.b    #TRUE,p_Parallel(a3)
  943.     move.b    #0,_ciaa+ciaddrb            ;make PB0-PB7 inputs
  944. .no_parrallel
  945.  
  946. * allocate Aura sampler
  947.     clr.l    p_AuraAddress(a3)
  948.     move.l    pb_CardResource(a5),d0
  949.     beq    .no_aura
  950.     move.l    d0,a6
  951.     call    GetCardMap
  952.     tst.l    d0
  953.     beq    .no_aura
  954.     move.l    d0,a0
  955.     move.l    cmm_IOMemory(a0),d2
  956.     beq    .no_aura
  957.  
  958.     move.l    pb_SysLib(a5),a6
  959.     moveq    #CardHandle_SIZEOF,d0
  960.     move.l    #MEMF_PUBLIC|MEMF_CLEAR,d1
  961.     call    AllocVec
  962.     move.l    d0,p_CardHandle(a3)
  963.     beq    .no_aura
  964.  
  965.     move.l    pb_CardResource(a5),a6
  966.     move.l    d0,a1
  967.     move.l    #IDString,LN_NAME(a1)
  968.     move.b    #CARDF_RESETREMOVE|CARDF_IFAVAILABLE,cah_CardFlags(a1)
  969.     call    OwnCard
  970.     tst.l    d0
  971.     bne    .no_aura
  972.  
  973.     move.l    p_CardHandle(a3),a1
  974.     call    BeginCardAccess
  975.  
  976.     move.l    d2,p_AuraAddress(a3)
  977. .no_aura
  978. .dontgetsampler
  979.  
  980.  
  981.  
  982. * initialize interrupts (Only dummy function pointers at this time)
  983.  
  984.  * p_PlayInt (the main playback interrupt)
  985.     move.b    #NT_INTERRUPT,LN_TYPE+p_PlayInt(a3)
  986.     move.l    #LibName,LN_NAME+p_PlayInt(a3)
  987.     move.l    #Interrupt_Dummy,IS_CODE+p_PlayInt(a3)
  988.     move.l    a3,IS_DATA+p_PlayInt(a3)
  989.  
  990.  * p_PlaySoftInt (caused by p_PlayInt, here are the mixing and conversion done)
  991.     move.b    #NT_INTERRUPT,LN_TYPE+p_PlaySoftInt(a3)
  992.     move.l    #LibName,LN_NAME+p_PlaySoftInt(a3)
  993.     move.l    #SoftInt_Dummy,IS_CODE+p_PlaySoftInt(a3)
  994.     move.l    a3,IS_DATA+p_PlaySoftInt(a3)
  995.  
  996.  * p_RecInt (the interrupt used for recording)
  997.     move.b    #NT_INTERRUPT,LN_TYPE+p_RecInt(a3)
  998.     move.l    #LibName,LN_NAME+p_RecInt(a3)
  999.     move.l    #Interrupt_Dummy,IS_CODE+p_RecInt(a3)
  1000.     clr.l    IS_DATA+p_RecInt(a3)
  1001.  
  1002.  * p_RecSoftInt (caused by p_RecInt when the record buffer has been filled)
  1003.     move.b    #32,LN_PRI+p_RecSoftInt(a3)
  1004.     move.b    #NT_INTERRUPT,LN_TYPE+p_RecSoftInt(a3)
  1005.     move.l    #LibName,LN_NAME+p_RecSoftInt(a3)
  1006.     move.l    #RecordSoftInt,IS_CODE+p_RecSoftInt(a3)
  1007.     move.l    a3,IS_DATA+p_RecSoftInt(a3)
  1008.  
  1009. * Make sure no interrupts occur until AHIsub_Start() is called
  1010.     move.w    #INTF_AUDIO,custom+INTENA
  1011.     move.w    #INTF_SETCLR,p_IRQMask(a3)
  1012.  
  1013. * Update ahiac_MixFreq to what the mixing/sampling frequency really is
  1014.     move.l    ahiac_MixFreq(a2),d1
  1015.     bsr    calcperiod
  1016.     move.l    d0,ahiac_MixFreq(a2)        ;store actual freq
  1017.  
  1018. * Save the filter state
  1019.     btst    #1,$bfe001
  1020.     seq    p_Filter(a3)
  1021.  
  1022. * Check the AHIpaulaFilterFreq variable.
  1023. * If the mixing frequency is higher than this one, set disable the filter,
  1024. * else enable it.
  1025.     moveq    #0,d5                ;Default freq
  1026.     move.l    pb_DosLib(a5),a6
  1027.     subq.l    #8,sp                ;local label
  1028.     move.w    #("0"<<8)|0,(sp)        ;Initialize as "0"
  1029.     lea    filterVar(pc),a0
  1030.     move.l    a0,d1
  1031.     move.l    sp,d2
  1032.     moveq.l    #8,d3
  1033.     moveq.l    #0,d4
  1034.     call    GetVar
  1035.     cmp.l    #-1,d0
  1036.     beq    .gotfreq
  1037.     move.l    sp,d1
  1038.     pea.l    0.w
  1039.     move.l    sp,d2
  1040.     call    StrToLong
  1041.     move.l    (sp)+,d5
  1042. .gotfreq
  1043.     addq.l    #8,sp
  1044. ; d5 is now the freq
  1045.  
  1046.     cmp.l    ahiac_MixFreq(a2),d5
  1047.     bls    .no_filter
  1048.     bclr    #1,$bfe001            ;turn audio filter on
  1049.     bra    .filter_set
  1050. .no_filter
  1051.     bset    #1,$bfe001            ;turn audio filter off
  1052. .filter_set
  1053.  
  1054.     btst.b    #PB_DMA,p_Flags(a3)
  1055.     beq    .mixing
  1056.  
  1057.     cmp.w    #4,ahiac_Channels(a2)
  1058.     bhi    .error_channels
  1059.  
  1060.     move.l    p_AudioFreq(a3),ahiac_MixFreq(a2)    ;store actual freq
  1061.  
  1062.     move.l    #AHIST_NOTYPE,p_Channels+channel_SIZEOF*0+ch_Type(a3)
  1063.     move.l    #AHIST_NOTYPE,p_Channels+channel_SIZEOF*1+ch_Type(a3)
  1064.     move.l    #AHIST_NOTYPE,p_Channels+channel_SIZEOF*2+ch_Type(a3)
  1065.     move.l    #AHIST_NOTYPE,p_Channels+channel_SIZEOF*3+ch_Type(a3)
  1066.     move.l    #AHIST_NOTYPE,p_Channels+channel_SIZEOF*0+ch_NextType(a3)
  1067.     move.l    #AHIST_NOTYPE,p_Channels+channel_SIZEOF*1+ch_NextType(a3)
  1068.     move.l    #AHIST_NOTYPE,p_Channels+channel_SIZEOF*2+ch_NextType(a3)
  1069.     move.l    #AHIST_NOTYPE,p_Channels+channel_SIZEOF*3+ch_NextType(a3)
  1070.     move.w    #0,p_Channels+channel_SIZEOF*0+ch_SndMsg+ahism_Channel(a3)
  1071.     move.w    #1,p_Channels+channel_SIZEOF*1+ch_SndMsg+ahism_Channel(a3)
  1072.     move.w    #2,p_Channels+channel_SIZEOF*2+ch_SndMsg+ahism_Channel(a3)
  1073.     move.w    #3,p_Channels+channel_SIZEOF*3+ch_SndMsg+ahism_Channel(a3)
  1074.  
  1075.     move.l    pb_SysLib(a5),a6
  1076.     move.w    ahiac_Sounds(a2),d0
  1077.     mulu.w    #sound_SIZEOF,d0
  1078.     move.l    #MEMF_PUBLIC|MEMF_CLEAR,d1
  1079.     call    AllocVec
  1080.     move.l    d0,p_Sounds(a3)
  1081.     beq    .error_nosoundmem
  1082.  
  1083.     move.l    d0,a0
  1084.     move.w    ahiac_Sounds(a2),d0
  1085.     subq.w    #1,d0
  1086. .fillsounds
  1087.     move.l    #AHIST_NOTYPE,so_Type(a0)
  1088.     add.w    #sound_SIZEOF,a0
  1089.     dbf    d0,.fillsounds
  1090.  
  1091.     tst.w    p_SwapChannels(a3)
  1092.     bne    .swapchannels
  1093.     move.l    #custom+AUD1,p_Channels+channel_SIZEOF*0+ch_RegBase(a3)
  1094.     move.l    #custom+AUD0,p_Channels+channel_SIZEOF*1+ch_RegBase(a3)
  1095.     move.l    #custom+AUD2,p_Channels+channel_SIZEOF*2+ch_RegBase(a3)
  1096.     move.l    #custom+AUD3,p_Channels+channel_SIZEOF*3+ch_RegBase(a3)
  1097.     move.w    #DMAF_AUD1,p_Channels+channel_SIZEOF*0+ch_DMAMask(a3)
  1098.     move.w    #DMAF_AUD0,p_Channels+channel_SIZEOF*1+ch_DMAMask(a3)
  1099.     move.w    #DMAF_AUD2,p_Channels+channel_SIZEOF*2+ch_DMAMask(a3)
  1100.     move.w    #DMAF_AUD3,p_Channels+channel_SIZEOF*3+ch_DMAMask(a3)
  1101.     move.w    #INTF_AUD1,p_Channels+channel_SIZEOF*0+ch_IntMask(a3)
  1102.     move.w    #INTF_AUD0,p_Channels+channel_SIZEOF*1+ch_IntMask(a3)
  1103.     move.w    #INTF_AUD2,p_Channels+channel_SIZEOF*2+ch_IntMask(a3)
  1104.     move.w    #INTF_AUD3,p_Channels+channel_SIZEOF*3+ch_IntMask(a3)
  1105.     move.w    #0,p_Channels+channel_SIZEOF*0+ch_Stereo(a3)
  1106.     move.w    #1,p_Channels+channel_SIZEOF*1+ch_Stereo(a3)
  1107.     move.w    #1,p_Channels+channel_SIZEOF*2+ch_Stereo(a3)
  1108.     move.w    #0,p_Channels+channel_SIZEOF*3+ch_Stereo(a3)
  1109.     bra    .storedbase
  1110. .swapchannels
  1111.     move.l    #custom+AUD0,p_Channels+channel_SIZEOF*0+ch_RegBase(a3)
  1112.     move.l    #custom+AUD1,p_Channels+channel_SIZEOF*1+ch_RegBase(a3)
  1113.     move.l    #custom+AUD3,p_Channels+channel_SIZEOF*2+ch_RegBase(a3)
  1114.     move.l    #custom+AUD2,p_Channels+channel_SIZEOF*3+ch_RegBase(a3)
  1115.     move.w    #DMAF_AUD0,p_Channels+channel_SIZEOF*0+ch_DMAMask(a3)
  1116.     move.w    #DMAF_AUD1,p_Channels+channel_SIZEOF*1+ch_DMAMask(a3)
  1117.     move.w    #DMAF_AUD3,p_Channels+channel_SIZEOF*2+ch_DMAMask(a3)
  1118.     move.w    #DMAF_AUD2,p_Channels+channel_SIZEOF*3+ch_DMAMask(a3)
  1119.     move.w    #INTF_AUD0,p_Channels+channel_SIZEOF*0+ch_IntMask(a3)
  1120.     move.w    #INTF_AUD1,p_Channels+channel_SIZEOF*1+ch_IntMask(a3)
  1121.     move.w    #INTF_AUD3,p_Channels+channel_SIZEOF*2+ch_IntMask(a3)
  1122.     move.w    #INTF_AUD2,p_Channels+channel_SIZEOF*3+ch_IntMask(a3)
  1123.     move.w    #1,p_Channels+channel_SIZEOF*0+ch_Stereo(a3)
  1124.     move.w    #0,p_Channels+channel_SIZEOF*1+ch_Stereo(a3)
  1125.     move.w    #0,p_Channels+channel_SIZEOF*2+ch_Stereo(a3)
  1126.     move.w    #1,p_Channels+channel_SIZEOF*3+ch_Stereo(a3)
  1127. .storedbase
  1128.  
  1129.  
  1130.     moveq    #0,d0
  1131.     bra    .exit
  1132.  
  1133. .mixing
  1134.     moveq    #AHISF_KNOWSTEREO|AHISF_KNOWHIFI|AHISF_CANRECORD|AHISF_MIXING|AHISF_TIMING,d0
  1135.  
  1136. .exit
  1137.     popm    std
  1138.     rts
  1139.  
  1140. .error_noaudiodev
  1141. .error_noreqmem
  1142. .error_noport
  1143. .error_nopaula
  1144. .error_channels
  1145. .error_nosoundmem
  1146.     moveq    #AHISF_ERROR,d0
  1147.     bra.b    .exit
  1148.  
  1149. .audiochannelarray
  1150.     dc.b    1+2+4+8
  1151. .audioname
  1152.     AUDIONAME
  1153. .calibname
  1154.     dc.b    "ENV:CyberSound/SoundDrivers/14Bit_Calibration",0
  1155.     even
  1156. .cardhandle:
  1157.     dc.l    0,0        ;ln_Succ, ln_Pred
  1158.     dc.b    0        ;ln_Type
  1159.     dc.b    0        ;ln_Pri
  1160.     dc.l    IDString    ;ln_Name
  1161.     dc.l    0,0,0        ;cah_CardRemoved, cah_CardInserted, cah_CardStatus
  1162.     dc.b    (CARDF_RESETREMOVE|CARDF_IFAVAILABLE)
  1163.     even
  1164.  
  1165. ;in:
  1166. * d1    MixFreq
  1167. * a3    paula
  1168. * a5    paulaBase
  1169. ;out:
  1170. * d0    New MixFreq
  1171. * d1.w    Period
  1172. ;description:
  1173. *    Calculate and return the best period and the actual frequency.
  1174. calcperiod:
  1175.     PRINTF    2,"calcperiod()"
  1176.     pushm    std
  1177.     move.l    p_AudioFreq(a3),d2
  1178.     move.l    d2,d0
  1179.     move.l    d1,d3
  1180.     move.l    pb_UtilLib(a5),a1
  1181.     jsr    _LVOUDivMod32(a1)
  1182.     lsl.l    #1,d1
  1183.     cmp.l    d3,d1
  1184.     bmi.b    .3
  1185.     addq.l    #1,d0
  1186. .3
  1187.     move.w    d0,d4
  1188. * d4 is now period. Check if is it a valid one, depending on current display mode
  1189.     bsr    checkvideo
  1190.     moveq    #MINPER,d1
  1191.     tst.l    d0
  1192.     bne    .5
  1193.     moveq    #MINPER*2,d1
  1194. .5
  1195.     cmp.w    d1,d4
  1196.     bhs.b    .6
  1197.     move.w    d1,d4
  1198. .6
  1199.     moveq    #0,d1
  1200.     move.w    d4,d1
  1201.     move.l    d2,d0
  1202.     move.l    d1,d3
  1203.     move.l    pb_UtilLib(a5),a1
  1204.     jsr    _LVOUDivMod32(a1)
  1205.     lsl.l    #1,d1
  1206.     cmp.l    d3,d1
  1207.     bmi.b    .4
  1208.     addq.l    #1,d0
  1209. .4
  1210.     move.w    d4,d1
  1211.     popm    std
  1212.     rts
  1213.  
  1214. ;in:
  1215. * a5    paulaBase
  1216. ;out:
  1217. * d0    TRUE if current mode is double
  1218. ;description:
  1219. *    Checks if the current screen mode is doublescan.
  1220. *    This routine is a bit ugly, but it does get the job
  1221. *    done, even if a graphic card is used.
  1222. checkvideo:
  1223.     PRINTF    2,"checkvideo"
  1224.  
  1225.     pushm    std
  1226.  
  1227. * Check the AHIpaulaSampleLimit variable.
  1228. * If 1, allow > 28 kHz frequencies, if 0, don't. If not present,
  1229. * check the screen mode.
  1230.     move.l    pb_DosLib(a5),a6
  1231.     clr.w    -(sp)                ;Initialize local data
  1232.     lea    screenVar(pc),a0
  1233.     move.l    a0,d1
  1234.     move.l    sp,d2
  1235.     moveq.l    #2,d3
  1236.     moveq.l    #0,d4
  1237.     call    GetVar
  1238.     move.w    (sp)+,d1
  1239.     cmp.l    #-1,d0
  1240.     beq    .testfreq
  1241.     cmp.w    #"0"<<8|0,d1
  1242.     beq    .no31k
  1243.     cmp.w    #"1"<<8|0,d1
  1244.     beq    .is31k
  1245.  
  1246. .testfreq
  1247.  
  1248. ; Chip revision test
  1249.  
  1250.     move.l    pb_GfxLib(a5),a0
  1251.     move.b    gb_ChipRevBits0(a0),d0
  1252.     and.b    #GFXF_HR_DENISE|GFXF_AA_LISA,d0
  1253.     beq    .no31k                ; OCS: No 31 kHz modes
  1254.  
  1255. ; Native screen test
  1256.  
  1257.     moveq    #0,d0
  1258.     move.l    pb_IntuiLib(a5),a6
  1259.     call    LockIBase
  1260.     move.l    d0,d2
  1261.     move.l    ib_FirstScreen(a6),a0
  1262.     lea    sc_ViewPort(a0),a0
  1263.     move.l    pb_GfxLib(a5),a6
  1264.     call    GetVPModeID
  1265.     move.l    d2,a0
  1266.     move.l    d0,d2
  1267.     move.l    pb_IntuiLib(a5),a6
  1268.     call    UnlockIBase
  1269.  
  1270.     ; "Check" if native screen
  1271.     move.l    d2,d0
  1272.     and.l    #$40000000,d0
  1273.     bne    .gfxcard
  1274.  
  1275.     ; It is!
  1276.     sub.w    #mtr_SIZEOF,sp            ;local storage
  1277.     suba.l    a0,a0
  1278.     move.l    sp,a1
  1279.     move.l    #mtr_SIZEOF,d0
  1280.     move.l    #DTAG_MNTR,d1
  1281.     move.l    pb_GfxLib(a5),a6
  1282.     call    GetDisplayInfoData
  1283.  
  1284.     moveq    #1,d1
  1285.     add.w    mtr_TotalRows(sp),d1
  1286.     sub.w    mtr_MinRow(sp),d1
  1287.     move.w    mtr_TotalColorClocks(sp),d2
  1288.     mulu.w    mtr_TotalRows(sp),d2
  1289.  
  1290.     add.w    #mtr_SIZEOF,sp            ;restore stack
  1291.     tst.l    d0
  1292.     beq    .no31k
  1293.     ; Calculate TotalColorClocks*TotalRows/(2*(TotalRows-MinRow+1)
  1294.     add.l    d1,d1
  1295.     beq    .no31k
  1296.     divu    d1,d2
  1297.     cmp.w    #64,d2                ; 64 is an round nice number, no?
  1298.     bls    .is31k
  1299.     bra    .no31k
  1300.  
  1301. .gfxcard
  1302.  
  1303. ; Picasso '96 test
  1304.  
  1305.     move.l    pb_SysLib(a5),a6
  1306.     lea    .picasso96(pc),a1
  1307.     call    Forbid                ; Not required, it's just to...
  1308.     call    FindTask
  1309.     call    Permit                ; ...make PatchWork happy.
  1310.     tst.l    d0
  1311.     beq    .cgfx                ; Not P96, assume CyberGraphX
  1312.  
  1313.     move.l    pb_DosLib(a5),a6
  1314.     clr.l    -(sp)                ;Initialize local data
  1315.     lea    .p96amigavideo(pc),a0
  1316.     move.l    a0,d1
  1317.     move.l    sp,d2
  1318.     moveq.l    #4,d3
  1319.     moveq.l    #0,d4
  1320.     call    GetVar
  1321.     move.l    (sp)+,d1
  1322.     swap.w    d1
  1323.     cmp.w    #"31",d1
  1324.     beq    .is31k
  1325.     bra    .no31k
  1326.  
  1327. .cgfx
  1328.  
  1329. ; CybergraphX test
  1330.  
  1331.     move.l    pb_GfxLib(a5),a0
  1332.     cmp.w    #39,LIB_VERSION(a0)
  1333.     beq    .known
  1334.     cmp.w    #40,LIB_VERSION(a0)
  1335.     beq    .known
  1336.     bra    .no31k
  1337. .known
  1338.     move.l    gb_copinit(a0),a0
  1339.     cmp.w    #$01FC,copinit_fm0(a0)        ;Security check (test if really FMODE)
  1340.     bne    .is31k                ;Probably an ECS machine.
  1341.                         ;Assume the user is clever enough
  1342.                         ;to use "AddAudioModes DBLSCAN"....
  1343.     move.w    copinit_fm0+2(a0),d0
  1344.     and.w    #$c000,d0            ;Mask sprite and bitplane double bit
  1345.     beq    .no31k
  1346. .is31k
  1347.     moveq    #TRUE,d0
  1348.     bra    .exit
  1349. .no31k
  1350.     moveq    #FALSE,d0
  1351. .exit
  1352.     popm    std
  1353.     rts
  1354. .picasso96
  1355.     dc.b    "Picasso96",0
  1356. .p96amigavideo
  1357.     dc.b    "Picasso96/AmigaVideo",0
  1358.     even
  1359.  
  1360. ;in:
  1361. * d0    Frequency
  1362. ;out:
  1363. * d0    Closest frequency
  1364. * d1    Index
  1365. findfreq:
  1366.     lea    freqlist(pc),a0
  1367.     cmp.l    (a0),d0
  1368.     bls.b    .2
  1369. .findfreq
  1370.     cmp.l    (a0)+,d0
  1371.     bhi.b    .findfreq
  1372.     move.l    -4(a0),d1
  1373.     sub.l    d0,d1
  1374.     sub.l    -8(a0),d0
  1375.     cmp.l    d1,d0
  1376.     bhs.b    .1
  1377.     subq.l    #4,a0
  1378. .1
  1379.     subq.l    #4,a0
  1380. .2
  1381.     move.l    (a0),d0
  1382.     move.l    a0,d1
  1383.     sub.l    #freqlist,d1
  1384.     lsr.l    #2,d1
  1385.     rts
  1386.  
  1387. freqlist:
  1388.     dc.l    4410                    ; CD/10
  1389.     dc.l    4800                    ; DAT/10
  1390.     dc.l    5513                    ; CD/8
  1391.     dc.l    6000                    ; DAT/8
  1392.     dc.l    7350                    ; CD/6
  1393.     dc.l    8000                    ; µ- and A-Law, DAT/6
  1394.     dc.l    9600                    ; DAT/5
  1395.     dc.l    11025                    ; CD/4
  1396.     dc.l    12000                    ; DAT/4
  1397.     dc.l    14700                    ; CD/3
  1398.     dc.l    16000                    ; DAT/3
  1399.     dc.l    17640                    ; CD/2.5
  1400.     dc.l    18900
  1401.     dc.l    19200                    ; DAT/2.5
  1402.     dc.l    22050                    ; CD/2
  1403.     dc.l    24000                    ; DAT/2
  1404.     dc.l    27429
  1405. FREQUENCIES_OCS        EQU    (*-freqlist)>>2
  1406.     dc.l    29400                    ; CD/1.5
  1407.     dc.l    32000                    ; DAT/1.5
  1408.     dc.l    33075
  1409.     dc.l    37800
  1410.     dc.l    44100                    ; CD
  1411.     dc.l    48000                    ; DAT
  1412. FREQUENCIES        EQU    (*-freqlist)>>2
  1413.     dc.l    -1
  1414.  
  1415. * _CreateTable directly stolen from Christian Buchner's CyberSound
  1416. * audio sub system (with permission).
  1417.  
  1418. * _CreateTable **************************************************************
  1419.  
  1420.         ; Parameters
  1421.  
  1422.         ; a0 = Table address
  1423.         ; (MUST have enough space for 65536 UWORDS)
  1424.         ; a1 = Additive Array
  1425.         ; 256 UBYTEs
  1426.         ;
  1427.         ; the table is organized as follows:
  1428.         ; 32768 UWORDS positive range, ascending order
  1429.         ; 32768 UWORDS negative range, ascending order
  1430.         ; access: (a0,d0.l*2)
  1431.         ; where d0.w is signed word sample data
  1432.         ; and the upper word of d0.l is *cleared!*
  1433.  
  1434.  
  1435. _CreateTable    movem.l    a2/d2-d6,-(sp)
  1436.  
  1437.         lea    128(a1),a2
  1438.  
  1439.         move.l    a2,a1            ; count the number of steps
  1440.         moveq    #128-1,d0        ; in the positive range
  1441.         moveq    #0,d5
  1442. .countpositive    move.b    (a1)+,d1
  1443.         ext.w    d1
  1444.         ext.l    d1
  1445.         add.l    d1,d5
  1446.         dbra    d0,.countpositive    ; d5=number of steps
  1447.         move.l    #32768,d6        ; reset stretch counter
  1448.  
  1449.         move.l    a2,a1            ; middle value in calibdata
  1450.         move.w    #32768-1,d0        ; number of positive values -1
  1451.         moveq    #0,d1            ; HI value
  1452.         moveq    #0,d2            ; LO value
  1453.         moveq    #0,d3            ; counter
  1454. .fetchnext2    move.b    (a1)+,d4        ; add calibtable to counter
  1455.         ext.w    d4
  1456.         add.w    d4,d3
  1457. .outerloop2    tst.w    d3
  1458.         bgt.s    .positive2
  1459. .negative2    addq.w    #1,d1            ; increment HI value
  1460.         sub.w    d4,d2            ; reset LO value
  1461.         bra.s    .fetchnext2
  1462. .positive2    move.b    d1,(a0)+        ; store HI and LO value
  1463.         move.b    d2,(a0)+
  1464.         sub.l    d5,d6            ; stretch the table
  1465.         bpl.s    .repeat2        ; to 32768 entries
  1466.         add.l    #32768,d6
  1467.         addq.w    #1,d2            ; increment LO value
  1468.         subq.w    #1,d3            ; decrement counter
  1469. .repeat2    dbra    d0,.outerloop2
  1470.  
  1471.         move.l    a2,a1            ; count the number of steps
  1472.         moveq    #128-1,d0        ; in the negative range
  1473.         moveq    #0,d5
  1474. .countnegative    move.b    -(a1),d1
  1475.         ext.w    d1
  1476.         ext.l    d1
  1477.         add.l    d1,d5
  1478.         dbra    d0,.countnegative    ; d5=number of steps
  1479.         move.l    #32768,d6        ; reset stretch counter
  1480.  
  1481.         add.l    #2*32768,a0        ; place at the end of the table
  1482.         move.l    a2,a1            ; middle value in calibdata
  1483.         move.w    #32768-1,d0        ; number of negative values -1
  1484.         moveq    #-1,d1            ; HI value
  1485.         moveq    #-1,d2            ; LO value
  1486.         moveq    #0,d3            ; counter
  1487. .fetchnext1    move.b    -(a1),d4        ; add calibtable to counter
  1488.         ext.w    d4
  1489.         add.w    d4,d3
  1490.         add.w    d4,d2            ; maximize LO value
  1491. .outerloop1    tst.w    d3
  1492.         bgt.s    .positive1
  1493. .negative1    subq.w    #1,d1
  1494.         bra.s    .fetchnext1
  1495. .positive1    move.b    d2,-(a0)        ; store LO and HI value
  1496.         move.b    d1,-(a0)
  1497.         sub.l    d5,d6            ; stretch the table
  1498.         bpl.s    .repeat1        ; to 32768 entries
  1499.         add.l    #32768,d6
  1500.         subq.w    #1,d2            ; decrement lo value
  1501.         subq.w    #1,d3            ; decrement counter
  1502. .repeat1    dbra    d0,.outerloop1
  1503.  
  1504.         movem.l    (sp)+,a2/d2-d6
  1505.         rts
  1506.  
  1507.  
  1508. ****** [driver].audio/AHIsub_FreeAudio **************************************
  1509. *
  1510. *   NAME
  1511. *       AHIsub_FreeAudio -- Deallocates the audio hardware.
  1512. *
  1513. *   SYNOPSIS
  1514. *       AHIsub_FreeAudio( audioctrl );
  1515. *                         A2
  1516. *
  1517. *       void AHIsub_FreeAudio( struct AHIAudioCtrlDrv * );
  1518. *
  1519. *   IMPLEMENTATION
  1520. *       Deallocate the audio hardware and other resources allocated in
  1521. *       AHIsub_AllocAudio(). AHIsub_Stop() will always be called by
  1522. *       'ahi.device' before this call is made.
  1523. *
  1524. *   INPUTS
  1525. *       audioctrl - pointer to an AHIAudioCtrlDrv structure.
  1526. *
  1527. *   NOTES
  1528. *       It must be safe to call this routine even if AHIsub_AllocAudio()
  1529. *       was never called, failed or called more than once.
  1530. *
  1531. *   SEE ALSO
  1532. *       AHIsub_AllocAudio()
  1533. *
  1534. *****************************************************************************
  1535. *
  1536. *
  1537.  
  1538. AHIsub_FreeAudio:
  1539.     PRINTF    2,"AHIsub_FreeAudio()"
  1540.     pushm    std
  1541.  
  1542.     move.l    a6,a5
  1543.     move.l    pb_SysLib(a5),a6
  1544.  
  1545.     move.l    ahiac_DriverData(a2),d0
  1546.     beq    .nopaula
  1547.     move.l    d0,a3
  1548.  
  1549.     move.l    p_Sounds(a3),d0
  1550.     beq.b    .nosounds
  1551.     move.l    d0,a1
  1552.     call    FreeVec
  1553. .nosounds
  1554.  
  1555.     move.l    p_CalibrationTable(a3),d0
  1556.     beq.b    .notable
  1557.     move.l    d0,a1
  1558.     call    FreeVec
  1559. .notable
  1560.  
  1561.     tst.b    p_Filter(a3)
  1562.     beq    .no_filter
  1563.     bclr    #1,$bfe001            ;turn audio filter on
  1564.     bra    .filter_set
  1565. .no_filter
  1566.     bset    #1,$bfe001            ;turn audio filter off
  1567. .filter_set
  1568.  
  1569.  
  1570.     tst.l    p_audiodev(a3)
  1571.     bne.b    .noaudiodev
  1572.     move.l    p_audioreq(a3),a1
  1573.     move.w    #CMD_RESET,IO_COMMAND(a1)    ;Restore audio interrupts
  1574.     bsr.w    BeginIO
  1575.     move.l    p_audioport(a3),a0
  1576.     call    WaitPort
  1577.     move.l    p_audioport(a3),a0
  1578.     call    GetMsg
  1579.     move.l    p_audioreq(a3),a1
  1580.     subq.l    #1,p_audiodev(a3)
  1581.     call    CloseDevice
  1582. .noaudiodev
  1583.     move.l    p_audioreq(a3),d0
  1584.     beq.b    .noaudioreq
  1585.     move.l    d0,a1
  1586.     call    FreeVec
  1587. .noaudioreq
  1588.     move.l    p_audioport(a3),d0
  1589.     beq.b    .noaudioport
  1590.     move.l    d0,a0
  1591.     call    DeleteMsgPort
  1592. .noaudioport
  1593.     tst.l    p_AuraAddress(a3)
  1594.     beq    .noaura
  1595.     move.l    pb_CardResource(a5),d0
  1596.     beq    .noaura
  1597.     move.l    d0,a6
  1598.     move.l    p_CardHandle(a3),d0
  1599.     beq    .noaura
  1600.     move.l    d0,a1
  1601.     call    EndCardAccess
  1602.     move.l    p_CardHandle(a3),a1
  1603.     moveq    #CARDF_REMOVEHANDLE,d0
  1604.     call    ReleaseCard
  1605. .noaura
  1606.     move.l    pb_SysLib(a5),a6
  1607.     move.l    p_CardHandle(a3),d0
  1608.     beq    .nocardhandle
  1609.     move.l    d0,a1
  1610.     call    FreeVec
  1611. .nocardhandle
  1612.     move.l    pb_MiscResource(a5),a6
  1613.     tst.l    p_ParPortUser(a3)
  1614.     bne.b    .noparport
  1615.     moveq    #MR_PARALLELPORT,d0
  1616.     jsr    MR_FREEMISCRESOURCE(a6)
  1617. .noparport
  1618.     tst.l    p_ParBitsUser(a3)
  1619.     bne.b    .noparbits
  1620.     moveq    #MR_PARALLELBITS,d0
  1621.     jsr    MR_FREEMISCRESOURCE(a6)
  1622. .noparbits
  1623.     tst.l    p_SerBitsUser(a3)
  1624.     bne.b    .noserbits
  1625.     moveq    #MR_SERIALBITS,d0
  1626.     jsr    MR_FREEMISCRESOURCE(a6)
  1627. .noserbits
  1628.     move.l    pb_SysLib(a5),a6
  1629.     move.l    a3,a1
  1630.     clr.l    ahiac_DriverData(a2)
  1631.     call    FreeVec
  1632. .nopaula
  1633.     moveq    #0,d0
  1634.     popm    std
  1635.     rts
  1636.  
  1637.  
  1638. ****** [driver].audio/AHIsub_Disable ****************************************
  1639. *
  1640. *   NAME
  1641. *       AHIsub_Disable -- Temporary turn off audio interrupt/task
  1642. *
  1643. *   SYNOPSIS
  1644. *       AHIsub_Disable( audioctrl );
  1645. *                       A2
  1646. *
  1647. *       void AHIsub_Disable( struct AHIAudioCtrlDrv * );
  1648. *
  1649. *   IMPLEMENTATION
  1650. *       If you are lazy, then call exec.library/Disable().
  1651. *       If you are smart, only disable your own interrupt or task.
  1652. *
  1653. *   INPUTS
  1654. *       audioctrl - pointer to an AHIAudioCtrlDrv structure.
  1655. *
  1656. *   NOTES
  1657. *       This call should be guaranteed to preserve all registers.
  1658. *       This call nests.
  1659. *
  1660. *   SEE ALSO
  1661. *       AHIsub_Enable(), exec.library/Disable()
  1662. *
  1663. *****************************************************************************
  1664. *
  1665. * MUST NOT REFERENCE a6!! (See PlayerFunc()!)
  1666. *
  1667.  
  1668. AHIsub_Disable:
  1669.     PRINTF    4,"AHIsub_Disable()"
  1670.     push    a3
  1671.     move.l    ahiac_DriverData(a2),a3
  1672.     addq.w    #1,p_DisableCount(a3)
  1673.     move.w    #INTF_AUDIO,custom+INTENA  ; Turn off ALL audio interrupts
  1674.     pop    a3
  1675.     rts
  1676.  
  1677.  
  1678. ****** [driver].audio/AHIsub_Enable *****************************************
  1679. *
  1680. *   NAME
  1681. *       AHIsub_Enable -- Turn on audio interrupt/task
  1682. *
  1683. *   SYNOPSIS
  1684. *       AHIsub_Enable( audioctrl );
  1685. *                      A2
  1686. *
  1687. *       void AHIsub_Enable( struct AHIAudioCtrlDrv * );
  1688. *
  1689. *   IMPLEMENTATION
  1690. *       If you are lazy, then call exec.library/Enable().
  1691. *       If you are smart, only enable your own interrupt or task.
  1692. *
  1693. *   INPUTS
  1694. *       audioctrl - pointer to an AHIAudioCtrlDrv structure.
  1695. *
  1696. *   NOTES
  1697. *       This call should be guaranteed to preserve all registers.
  1698. *       This call nests.
  1699. *
  1700. *   SEE ALSO
  1701. *       AHIsub_Disable(), exec.library/Enable()
  1702. *
  1703. *****************************************************************************
  1704. *
  1705. * MUST NOT REFERENCE a6!! (See PlayerFunc()!)
  1706. *
  1707.  
  1708. AHIsub_Enable:
  1709.     PRINTF    4,"AHIsub_Enable()"
  1710.     push    a3
  1711.     move.l    ahiac_DriverData(a2),a3
  1712.     subq.w    #1,p_DisableCount(a3)
  1713.     bne    .exit
  1714.     move.w    p_IRQMask(a3),custom+INTENA
  1715. .exit
  1716.     pop    a3
  1717.     rts
  1718.  
  1719.  
  1720. ****** [driver].audio/AHIsub_Start ******************************************
  1721. *
  1722. *   NAME
  1723. *       AHIsub_Start -- Starts playback or recording
  1724. *
  1725. *   SYNOPSIS
  1726. *       error = AHIsub_Start( flags, audioctrl );
  1727. *       D0                    D0     A2
  1728. *
  1729. *       ULONG AHIsub_Start(ULONG, struct AHIAudioCtrlDrv * );
  1730. *
  1731. *   IMPLEMENTATION
  1732. *       What to do depends what you returned in AHIsub_AllocAudio().
  1733. *
  1734. *     * First, assume bit AHISB_PLAY in flags is set. This means that you
  1735. *       should begin playback.
  1736. *
  1737. *     - AHIsub_AllocAudio() returned AHISF_MIXING|AHISF_TIMING:
  1738. *
  1739. *       A) Allocate a mixing buffer of ahiac_BuffSize bytes. The buffer must
  1740. *          be long aligned!
  1741. *       B) Create/start an interrupt or task that will do 1-6 over and over
  1742. *          again until AHIsub_Stop() is called. Note that it is not a good
  1743. *          idea to do the actual mixing and conversion in a real hardware
  1744. *          interrupt. Signal a task or create a Software Interrupt to do
  1745. *          the number crunching.
  1746. *
  1747. *       1) Call the user Hook ahiac_PlayerFunc with the following parameters:
  1748. *                  A0 - (struct Hook *)
  1749. *                  A2 - (struct AHIAudioCtrlDrv *)
  1750. *                  A1 - Set to NULL.
  1751. *
  1752. *       2) [Call the ahiac_PreTimer function. If it returns TRUE (Z will be
  1753. *          cleared so you don't have to test d0), skip step 3 and 4. This
  1754. *          is used to avoid overloading the CPU. This step is optional.
  1755. *          A2 is assumed to point to struct AHIAudioCtrlDrv. All registers
  1756. *          except d0 are preserved.  (V4)]
  1757. *
  1758. *       3) Call the mixing Hook (ahiac_MixerFunc) with the following
  1759. *          parameters:
  1760. *                  A0 - (struct Hook *)           - The Hook itself
  1761. *                  A2 - (struct AHIAudioCtrlDrv *)
  1762. *                  A1 - (WORD *[])                - The mixing buffer.
  1763. *          Note that ahiac_MixerFunc preserves ALL registers.
  1764. *          The user Hook ahiac_SoundFunc will be called by the mixing
  1765. *          routine when a sample have been processed, so you don't have to
  1766. *          worry about that.
  1767. *          How the buffer will be filled is indicated by ahiac_Flags.
  1768. *          It is always filled with signed 16-bit (32 bit if AHIACB_HIFI in
  1769. *          in ahiac_Flags is set) words, even if playback is 8 bit. If
  1770. *          AHIDBB_STEREO is set (in ahiac_Flags), data for left and right
  1771. *          channel are interleaved:
  1772. *           1st sample left channel,
  1773. *           1st sample right channel,
  1774. *           2nd sample left channel,
  1775. *           ...,
  1776. *           ahiac_BuffSamples:th sample left channel,
  1777. *           ahiac_BuffSamples:th sample right channel.
  1778. *          If AHIDBB_STEREO is cleared, the mono data is stored:
  1779. *           1st sample,
  1780. *           2nd sample,
  1781. *           ...,
  1782. *           ahiac_BuffSamples:th sample.
  1783. *          Note that neither AHIACB_STEREO nor AHIACB_HIFI will be set if
  1784. *          you didn't report that you understand these flags when
  1785. *          AHI_AllocAudio() was called.
  1786. *
  1787. *          For AHI V2, the type of buffer is also available in ahiac_BuffType.
  1788. *          It is suggested that you use this value instead. ahiac_BuffType
  1789. *          can be one of AHIST_M16S, AHIST_S16S, AHIST_M32S and AHIST_S32S.
  1790. *
  1791. *       4) Convert the buffer if needed and feed it to the audio hardware.
  1792. *          Note that you may have to clear CPU caches if you are using DMA
  1793. *          to play the buffer, and the buffer is not allocated in non-
  1794. *          cachable RAM.
  1795. *
  1796. *       5) [Call the ahiac_PostTimer function. A2 is assumed to point to
  1797. *          struct AHIAudioCtrlDrv. All registers are preserved.  (V4)]
  1798. *
  1799. *       6) Wait until the whole buffer has been played, then repeat.
  1800. *
  1801. *       Use double buffering if possible!
  1802. *
  1803. *       You may DECREASE ahiac_BuffSamples slightly, for example to force an
  1804. *       even number of samples to be mixed. By doing this you will make
  1805. *       ahiac_PlayerFunc to be called at wrong frequency so be careful!
  1806. *       Even if ahiac_BuffSamples is defined ULONG, it will never be greater
  1807. *       than 65535.
  1808. *
  1809. *       ahiac_BuffSize is the largest size of the mixing buffer that will be
  1810. *       needed until AHIsub_Stop() is called.
  1811. *
  1812. *       ahiac_MaxBuffSamples is the maximum number of samples that will be
  1813. *       mixed (until AHIsub_Stop() is called). You can use this value if you
  1814. *       need to allocate DMA buffers.
  1815. *
  1816. *       ahiac_MinBuffSamples is the minimum number of samples that will be
  1817. *       mixed. Most drivers will ignore it.
  1818. *
  1819. *       If AHIsub_AllocAudio() returned with the AHISB_CANPOSTPROCESS bit set,
  1820. *       ahiac_BuffSize is large enough to hold two buffers. The mixing buffer
  1821. *       will be filled with the wet buffer first, immediately followed by the
  1822. *       dry buffer. I.e., ahiac_BuffSamples sample frames wet data, then
  1823. *       ahiac_BuffSamples sample frames dry data. The DSP fx should only be
  1824. *       applied to the wet buffer, and the two buffers should then be added
  1825. *       together. (V4)
  1826. *
  1827. *     - If AHIsub_AllocAudio() returned AHISF_MIXING, do as described above,
  1828. *       except calling ahiac_PlayerFunc. ahiac_PlayerFunc should be called
  1829. *       ahiac_PlayerFreq times per second, clocked by timers on your sound
  1830. *       card or by using 'timer.device' or 'realtime.library'. No other Amiga
  1831. *       resources may be used for timing (like direct CIA timers).
  1832. *       ahiac_MinBuffSamples and ahiac_MaxBuffSamples are undefined if
  1833. *       AHIsub_AllocAudio() returned AHISF_MIXING (AHISB_TIMING bit not set).
  1834. *
  1835. *     - If AHIsub_AllocAudio() returned with neither the AHISB_MIXING nor
  1836. *       the AHISB_TIMING bit set, then just start playback. Don't forget to
  1837. *       call ahiac_PlayerFunc ahiac_PlayerFreq times per second. Only your
  1838. *       own timing hardware, 'timer.device'  or 'realtime.library' may be
  1839. *       used. Note that ahiac_MixerFunc, ahiac_BuffSamples,
  1840. *       ahiac_MinBuffSamples, ahiac_MaxBuffSamples and ahiac_BuffSize are
  1841. *       undefined. ahiac_MixFreq is the frequency the user wants to use for
  1842. *       recording, if you support that.
  1843. *
  1844. *     * Second, assume bit AHISB_RECORD in flags is set. This means that you
  1845. *       should start to sample. Create a interrupt or task that does the
  1846. *       following:
  1847. *
  1848. *       Allocate a buffer (you chose size, but try to keep it reasonable
  1849. *       small to avoid delays - it is suggested that RecordFunc is called
  1850. *       at least 4 times/second for the lowers sampling rate, and more often
  1851. *       for higher rates), and fill it with the sampled data. The buffer must
  1852. *       be long aligned, and it's size must be evenly divisible by four.
  1853. *       The format should always be AHIST_S16S (even with 8 bit mono samplers),
  1854. *       which means:
  1855. *           1st sample left channel,
  1856. *           1st sample right channel (same as prev. if mono),
  1857. *           2nd sample left channel,
  1858. *           ... etc.
  1859. *       Each sample is a signed word (WORD). The sample rate should be equal
  1860. *       to the mixing rate.
  1861. *
  1862. *       Call the ahiac_SamplerFunc Hook with the following parameters:
  1863. *           A0 - (struct Hook *)           - The Hook itself
  1864. *           A2 - (struct AHIAudioCtrlDrv *)
  1865. *           A1 - (struct AHIRecordMessage *)
  1866. *       The message should be filled as follows:
  1867. *           ahirm_Type - Set to AHIST_S16S.
  1868. *           ahirm_Buffer - A pointer to the filled buffer.
  1869. *           ahirm_Samples - How many sample frames stored.
  1870. *       You must not destroy the buffer until next time the Hook is called.
  1871. *
  1872. *       Repeat until AHIsub_Stop() is called.
  1873. *
  1874. *     * Note that both bits may be set when this function is called.
  1875. *
  1876. *   INPUTS
  1877. *       flags - See <libraries/ahi_sub.h>.
  1878. *       audioctrl - pointer to an AHIAudioCtrlDrv structure.
  1879. *
  1880. *   RESULT
  1881. *       Returns AHIE_OK if successful, else an error code as defined
  1882. *       in <devices/ahi.h>. AHIsub_Stop() will always be called, even
  1883. *       if this call failed.
  1884. *
  1885. *   NOTES
  1886. *       The driver must be able to handle multiple calls to this routine
  1887. *       without preceding calls to AHIsub_Stop().
  1888. *
  1889. *   SEE ALSO
  1890. *       AHIsub_Update(), AHIsub_Stop()
  1891. *
  1892. *****************************************************************************
  1893. *
  1894. *
  1895. *
  1896.  
  1897. AHIsub_Start:
  1898.     PRINTF    2,"AHIsub_Start()"
  1899.  
  1900.     pushm    std
  1901.  
  1902.     move.l    d0,d7
  1903.     lea    custom,a4
  1904.     move.l    ahiac_DriverData(a2),a3
  1905.  
  1906.     btst    #AHISB_PLAY,d7
  1907.     beq    .dont_play
  1908.  
  1909. **
  1910. *** AHISB_PLAY
  1911. **
  1912.     moveq    #AHISF_PLAY,d0
  1913.     call    AHIsub_Stop            ;Stop current playback if any.
  1914.     call    AHIsub_Update            ;fill variables
  1915.  
  1916.     move.l    a6,a5
  1917.     move.l    pb_SysLib(a5),a6
  1918.  
  1919.     btst    #PB_DMA,p_Flags(a3)
  1920.     beq    .no_dma
  1921.     bsr    DMA_Start
  1922.     bra    .exit
  1923. .no_dma
  1924.  
  1925.     move.l    ahiac_BuffSize(a2),d0
  1926.     move.l    #MEMF_PUBLIC|MEMF_CLEAR,d1
  1927.     call    AllocVec
  1928.     move.l    d0,p_Mixbuffer(a3)
  1929.     beq    .error_nomem
  1930.  
  1931.     move.l    ahiac_MixFreq(a2),d1
  1932.     bsr.w    calcperiod
  1933.     move.w    d1,p_AudPer(a3)
  1934.  
  1935. * The init*bit?  routines allocates p_DMAbuffer, sets up
  1936. * p_AudPtr, sets the volume, stores the correct interrupt routines in
  1937. * p_PlayInt's and p_PlaySoftInt's IS_CODE.
  1938.  
  1939.     pea    .1(pc)
  1940.     move.b    p_Flags(a3),d0
  1941.     and.b    #PF_STEREO|PF_14BIT,d0
  1942.     beq.w    init8bitM
  1943.     cmp.b    #PF_STEREO,d0
  1944.     beq.w    init8bitS
  1945.     cmp.b    #PF_14BIT,d0
  1946.     beq.w    init14bitM
  1947.     bra.w    init14bitS
  1948. .1
  1949.     tst.l    d0
  1950.     bne    .exit
  1951.  
  1952. * Install play interrupt
  1953.     lea    p_PlayInt(a3),a1
  1954.     moveq    #INTB_AUD0,d0
  1955.     call    SetIntVector
  1956.     clr.w    p_DisableCount(a3)
  1957.  
  1958.     or.w    #INTF_SETCLR|INTF_AUD0,p_IRQMask(a3)
  1959.     move.w    #INTF_SETCLR|INTF_AUD0,INTENA(a4)    ;enable
  1960.     move.w    #INTF_SETCLR|INTF_AUD0,INTREQ(a4)    ;start
  1961.  
  1962.     move.l    a5,a6
  1963.  
  1964.  
  1965. .dont_play
  1966.     btst    #AHISB_RECORD,d7
  1967.     beq    .dont_record
  1968. **
  1969. *** AHISB_RECORD
  1970. **
  1971.     moveq    #0,d0
  1972.     move.b    p_Flags(a3),d0            ;Sanity check...
  1973.     and.b    #PF_14BIT|PF_DMA,d0
  1974.     bne    .error_unknown
  1975.  
  1976.     moveq    #AHISF_RECORD,d0
  1977.     call    AHIsub_Stop            ;Stop current recording if any.
  1978.  
  1979.     move.l    a6,a5
  1980.     move.l    pb_SysLib(a5),a6
  1981.  
  1982.     move.l    #RECORDSAMPLES*4,d0
  1983.     move.l    #MEMF_PUBLIC,d1
  1984.     call    AllocVec
  1985.     move.l    d0,p_RecBuffer1(a3)
  1986.     beq    .error_nomem
  1987.  
  1988.     move.l    d0,p_RecFillPtr(a3)
  1989.     move.w    #RECORDSAMPLES,p_RecFillCount(a3)
  1990.  
  1991.     move.l    #RECORDSAMPLES*4,d0
  1992.     move.l    #MEMF_PUBLIC,d1
  1993.     call    AllocVec
  1994.     move.l    d0,p_RecBuffer2(a3)
  1995.     beq    .error_nomem
  1996.  
  1997.     move.l    ahiac_MixFreq(a2),d1
  1998.     bsr.w    calcperiod
  1999.     lsr.w    #1,d1                ;Period/2 => Frequency·2
  2000.     move.w    d1,AUD2PER(a4)
  2001.     move.w    d1,AUD3PER(a4)
  2002.     move.w    p_MonitorVolume(a3),d0
  2003.     move.w    d0,AUD2VOL(a4)
  2004.     move.w    d0,AUD3VOL(a4)
  2005.  
  2006. * Install record interrupt
  2007.     move.w    p_Input(a3),d0
  2008.     beq    .parsampler
  2009.     cmp.w    #1,d0
  2010.     beq    .aurasampler
  2011.     cmp.w    #2,d0
  2012.     beq    .clarity
  2013.     bra    .error_unknown
  2014.  
  2015. .parsampler
  2016.     tst.b    p_Parallel(a3)            ;Parrallel port allocated?
  2017.     beq    .error_unknown
  2018.     lea    p_RecIntData(a3),a1
  2019.     move.l    a1,IS_DATA+p_RecInt(a3)
  2020.     move.l    #RecordInterrupt,IS_CODE+p_RecInt(a3)
  2021.  
  2022.     move.b    #$ff,_ciab+ciaddrb        ; Set parallel port to output
  2023.  
  2024.     bra    .setrecint
  2025.  
  2026. .clarity
  2027.     tst.b    p_Parallel(a3)            ;Parrallel port allocated?
  2028.     beq    .error_unknown
  2029.  
  2030.     move.l    pb_MiscResource(a5),a6
  2031.     move.l    #MR_SERIALBITS,d0    ; allocate serial port control lines
  2032.     lea    IDString(pc),a1
  2033.     jsr    MR_ALLOCMISCRESOURCE(a6)
  2034.     move.l    d0,p_SerBitsUser(a3)
  2035.     bne    .error_unknown
  2036.  
  2037.     lea    p_RecIntData(a3),a1
  2038.     move.l    a1,IS_DATA+p_RecInt(a3)
  2039.     move.l    #RecordInterruptClarity,IS_CODE+p_RecInt(a3)
  2040.  
  2041.     ; Set DTR, PRTBUSY and PRTRPOUT to outputs
  2042.     or.b    #CIAF_COMDTR!CIAF_PRTRBUSY!CIAF_PRTRPOUT,_ciab+ciaddra
  2043.     move.b    #$ff,_ciab+ciaddrb        ; Set parallel port to output
  2044.     ; Reset Clarity
  2045.     move.b    #CIAF_PRTRBUSY!CIAF_PRTRPOUT,_ciab+ciapra
  2046.     move.b    #CIAF_PRTRPOUT,_ciab+ciapra
  2047.     move.b    #CIAF_PRTRBUSY!CIAF_PRTRPOUT,_ciab+ciapra
  2048.     ; Clarity is now in stereo record mode
  2049.  
  2050.     bra    .setrecint
  2051.  
  2052. .aurasampler
  2053.     tst.l    p_AuraAddress(a3)        ;Aura sampler allocated?
  2054.     beq    .error_unknown
  2055.     lea    p_RecIntDataAura(a3),a1
  2056.     move.l    a1,IS_DATA+p_RecInt(a3)
  2057.     move.l    #RecordInterruptAura,IS_CODE+p_RecInt(a3)
  2058.     bra    .setrecint
  2059.  
  2060. .setrecint
  2061.     move.l    pb_SysLib(a5),a6
  2062.     lea    p_RecInt(a3),a1
  2063.     moveq    #INTB_AUD3,d0
  2064.     call    SetIntVector
  2065.  
  2066.     move.w    #DMAF_AUD2|DMAF_AUD3,DMACON(a4)        ;disable DMA
  2067.     or.w    #INTF_SETCLR|INTF_AUD3,p_IRQMask(a3)
  2068.     move.w    #INTF_SETCLR|INTF_AUD3,INTENA(a4)    ;enable
  2069.     move.w    #INTF_SETCLR|INTF_AUD3,INTREQ(a4)    ;start
  2070.  
  2071. .dont_record
  2072. .return
  2073.     moveq    #AHIE_OK,d0
  2074. .exit
  2075.     popm    std
  2076.     rts
  2077. .error_nomem
  2078.     moveq    #AHIE_NOMEM,d0
  2079.     bra.b    .exit
  2080. .error_unknown
  2081.     moveq    #AHIE_UNKNOWN,d0
  2082.     bra.b    .exit
  2083.  
  2084.  
  2085. ;in:
  2086. * a2    AudioCtrl
  2087. * a3    paula
  2088. * a4    custom
  2089. * a5    paulaBase
  2090. * a6    ExecBase
  2091. init8bitM:
  2092.     PRINTF    2,"init8bitM()"
  2093.     move.l    #AudioInterrupt2,IS_CODE+p_PlayInt(a3)
  2094.     move.l    #SoftInt_8bitM,IS_CODE+p_PlaySoftInt(a3)
  2095.     move.b    p_Flags(a3),d0
  2096.     btst    #PB_HIFI,d0
  2097.     beq    .nohifi
  2098.     move.l    #SoftInt_8bitMH,IS_CODE+p_PlaySoftInt(a3)
  2099. .nohifi
  2100.  
  2101.     move.l    p_MinBufferLength(a3),d0
  2102.     add.l    ahiac_MaxBuffSamples(a2),d0    ;Max. # of 8 bit samples
  2103.     addq.l    #3,d0
  2104.     and.b    #~3,d0                ;make it a multiple of 4
  2105.     move.l    d0,d2                ;d2 = channel size
  2106.  
  2107.     lsl.l    #1,d0                ;Double buffer
  2108.     move.l    #MEMF_CHIP|MEMF_PUBLIC|MEMF_CLEAR,d1
  2109.     call    AllocVec
  2110.     move.l    d0,p_DMAbuffer(a3)
  2111.     beq    .nomem
  2112.  
  2113.     move.l    d0,p_AudPtr1A(a3)
  2114.     move.l    d0,p_AudPtr2A(a3)
  2115.     add.l    d2,d0
  2116.     move.l    d0,p_AudPtr1B(a3)
  2117.     move.l    d0,p_AudPtr2B(a3)
  2118.  
  2119. ;    move.w    #64,AUD0VOL(a4)
  2120. ;    move.w    #64,AUD1VOL(a4)
  2121.  
  2122.     moveq    #0,d0
  2123.     rts
  2124. .nomem
  2125.     moveq    #AHIE_NOMEM,d0
  2126.     rts
  2127.  
  2128. ;in:
  2129. * a2    AudioCtrl
  2130. * a3    paula
  2131. * a5    paulaBase
  2132. * a6    ExecBase
  2133. init8bitS:
  2134.     PRINTF    2,"init8bitS()"
  2135.     move.l    #AudioInterrupt2,IS_CODE+p_PlayInt(a3)
  2136.     move.l    #SoftInt_8bitS,IS_CODE+p_PlaySoftInt(a3)
  2137.     move.b    p_Flags(a3),d0
  2138.     btst    #PB_HIFI,d0
  2139.     beq    .nohifi
  2140.     move.l    #SoftInt_8bitSH,IS_CODE+p_PlaySoftInt(a3)
  2141. .nohifi
  2142.  
  2143.     move.l    p_MinBufferLength(a3),d0
  2144.     add.l    ahiac_MaxBuffSamples(a2),d0    ;Max. # of 8 bit samples
  2145.     addq.l    #3,d0
  2146.     and.b    #~3,d0                ;make it a multiple of 4
  2147.     move.l    d0,d2                ;d2 = channel size
  2148.  
  2149.     lsl.l    #2,d0                ;Double buffer + Stereo
  2150.     move.l    #MEMF_CHIP|MEMF_PUBLIC|MEMF_CLEAR,d1
  2151.     call    AllocVec
  2152.     move.l    d0,p_DMAbuffer(a3)
  2153.     beq    .nomem
  2154.  
  2155.     move.l    d0,p_AudPtr1A(a3)
  2156.     add.l    d2,d0
  2157.     move.l    d0,p_AudPtr2A(a3)
  2158.     add.l    d2,d0
  2159.     move.l    d0,p_AudPtr1B(a3)
  2160.     add.l    d2,d0
  2161.     move.l    d0,p_AudPtr2B(a3)
  2162.  
  2163. ;    move.w    #64,AUD0VOL(a4)
  2164. ;    move.w    #64,AUD1VOL(a4)
  2165.  
  2166.     moveq    #0,d0
  2167.     rts
  2168. .nomem
  2169.     moveq    #AHIE_NOMEM,d0
  2170.     rts
  2171.  
  2172. ;in:
  2173. * a2    AudioCtrl
  2174. * a3    paula
  2175. * a5    paulaBase
  2176. * a6    ExecBase
  2177. init14bitM:
  2178.     PRINTF    2,"init14bitM()"
  2179.     move.l    #AudioInterrupt4,IS_CODE+p_PlayInt(a3)
  2180.     lea    SoftInt_14bitM(pc),a0
  2181.     move.b    p_Flags(a3),d0
  2182.     btst    #PB_HIFI,d0
  2183.     beq    .nohifi1
  2184.     lea    SoftInt_14bitMH(pc),a0
  2185. .nohifi1
  2186.     tst.l    p_CalibrationTable(a3)
  2187.     beq.b    .nocalib
  2188.     lea    SoftInt_14CbitM(pc),a0
  2189.     move.b    p_Flags(a3),d0
  2190.     btst    #PB_HIFI,d0
  2191.     beq    .nohifi2
  2192.     lea    SoftInt_14CbitMH(pc),a0
  2193. .nohifi2
  2194. .nocalib
  2195.     move.l    a0,IS_CODE+p_PlaySoftInt(a3)
  2196.  
  2197.     move.l    p_MinBufferLength(a3),d0
  2198.     add.l    ahiac_MaxBuffSamples(a2),d0    ;Max. # of 16 bit samples
  2199.     addq.l    #3,d0
  2200.     and.b    #~3,d0                ;make it a multiple of 4
  2201.     move.l    d0,d2                ;d2 = channel size
  2202.  
  2203.     lsl.l    #2,d0                ;Double buffer + 2×8 bit
  2204.     move.l    #MEMF_CHIP|MEMF_PUBLIC|MEMF_CLEAR,d1
  2205.     call    AllocVec
  2206.     move.l    d0,p_DMAbuffer(a3)
  2207.     beq    .nomem
  2208.  
  2209.     move.l    d0,p_AudPtr1A(a3)
  2210.     move.l    d0,p_AudPtr2A(a3)
  2211.     add.l    d2,d0
  2212.     move.l    d0,p_AudPtr4A(a3)
  2213.     move.l    d0,p_AudPtr3A(a3)
  2214.     add.l    d2,d0
  2215.     move.l    d0,p_AudPtr1B(a3)
  2216.     move.l    d0,p_AudPtr2B(a3)
  2217.     add.l    d2,d0
  2218.     move.l    d0,p_AudPtr4B(a3)
  2219.     move.l    d0,p_AudPtr3B(a3)
  2220.  
  2221. ;    move.w    #64,AUD0VOL(a4)
  2222. ;    move.w    #64,AUD1VOL(a4)
  2223. ;    move.w    #1,AUD2VOL(a4)
  2224. ;    move.w    #1,AUD3VOL(a4)
  2225.  
  2226.     moveq    #0,d0
  2227.     rts
  2228. .nomem
  2229.     moveq    #AHIE_NOMEM,d0
  2230.     rts
  2231.  
  2232. ;in:
  2233. * a2    AudioCtrl
  2234. * a3    paula
  2235. * a5    paulaBase
  2236. * a6    ExecBase
  2237. init14bitS:
  2238.     PRINTF    2,"init14bitS()"
  2239.     move.l    #AudioInterrupt4,IS_CODE+p_PlayInt(a3)
  2240.     lea    SoftInt_14bitS(pc),a0
  2241.     move.b    p_Flags(a3),d0
  2242.     btst    #PB_HIFI,d0
  2243.     beq    .nohifi1
  2244.     lea    SoftInt_14bitSH(pc),a0
  2245. .nohifi1
  2246.     tst.l    p_CalibrationTable(a3)
  2247.     beq.b    .nocalib
  2248.     lea    SoftInt_14CbitS(pc),a0
  2249.     move.b    p_Flags(a3),d0
  2250.     btst    #PB_HIFI,d0
  2251.     beq    .nohifi2
  2252.     lea    SoftInt_14CbitSH(pc),a0
  2253. .nohifi2
  2254. .nocalib
  2255.     move.l    a0,IS_CODE+p_PlaySoftInt(a3)
  2256.  
  2257.     move.l    p_MinBufferLength(a3),d0
  2258.     add.l    ahiac_MaxBuffSamples(a2),d0    ;Max. # of 16 bit samples
  2259.     addq.l    #3,d0
  2260.     and.b    #~3,d0                ;make it a multiple of 4
  2261.     move.l    d0,d2                ;d2 = channel size
  2262.  
  2263.     lsl.l    #3,d0                ;Double buffer + 2×8 bit + Stereo
  2264.     move.l    #MEMF_CHIP|MEMF_PUBLIC|MEMF_CLEAR,d1
  2265.     call    AllocVec
  2266.     move.l    d0,p_DMAbuffer(a3)
  2267.     beq    .nomem
  2268.  
  2269.     move.l    d0,p_AudPtr1A(a3)
  2270.     add.l    d2,d0
  2271.     move.l    d0,p_AudPtr2A(a3)
  2272.     add.l    d2,d0
  2273.     move.l    d0,p_AudPtr3A(a3)
  2274.     add.l    d2,d0
  2275.     move.l    d0,p_AudPtr4A(a3)
  2276.     add.l    d2,d0
  2277.     move.l    d0,p_AudPtr1B(a3)
  2278.     add.l    d2,d0
  2279.     move.l    d0,p_AudPtr2B(a3)
  2280.     add.l    d2,d0
  2281.     move.l    d0,p_AudPtr3B(a3)
  2282.     add.l    d2,d0
  2283.     move.l    d0,p_AudPtr4B(a3)
  2284.  
  2285. ;    move.w    #64,AUD0VOL(a4)
  2286. ;    move.w    #64,AUD1VOL(a4)
  2287. ;    move.w    #1,AUD2VOL(a4)
  2288. ;    move.w    #1,AUD3VOL(a4)
  2289.  
  2290.     moveq    #0,d0
  2291.     rts
  2292. .nomem
  2293.     moveq    #AHIE_NOMEM,d0
  2294.     rts
  2295.  
  2296.  
  2297. ****** [driver].audio/AHIsub_Update *****************************************
  2298. *
  2299. *   NAME
  2300. *       AHIsub_Update -- Update some variables
  2301. *
  2302. *   SYNOPSIS
  2303. *       AHIsub_Update( flags, audioctrl );
  2304. *                      D0     A2
  2305. *
  2306. *       void AHIsub_Update(ULONG, struct AHIAudioCtrlDrv * );
  2307. *
  2308. *   IMPLEMENTATION
  2309. *       All you have to do is to update some variables:
  2310. *
  2311. *     * Mixing & timing: ahiac_PlayerFunc, ahiac_MixerFunc, ahiac_SamplerFunc,
  2312. *       ahiac_BuffSamples (and perhaps ahiac_PlayerFreq if you use it).
  2313. *
  2314. *     * Mixing only: ahiac_PlayerFunc, ahiac_MixerFunc, ahiac_SamplerFunc and
  2315. *           ahiac_PlayerFreq.
  2316. *
  2317. *     * Nothing: ahiac_PlayerFunc, ahiac_SamplerFunc and ahiac_PlayerFreq.
  2318. *
  2319. *   INPUTS
  2320. *       flags - Currently no flags defined.
  2321. *       audioctrl - pointer to an AHIAudioCtrlDrv structure.
  2322. *
  2323. *   RESULT
  2324. *
  2325. *   NOTES
  2326. *       This call must be safe from interrupts.
  2327. *
  2328. *   SEE ALSO
  2329. *       AHIsub_Start()
  2330. *
  2331. *****************************************************************************
  2332. *
  2333. *
  2334. *
  2335.  
  2336. AHIsub_Update:
  2337.     PRINTF    2,"AHIsub_Update()"
  2338.     pushm    std
  2339.  
  2340.     call    AHIsub_Disable        ;make sure we don't get an interrupt
  2341.                     ;while updating our local variables
  2342.     move.l    ahiac_DriverData(a2),a3
  2343.  
  2344.     move.l    ahiac_PlayerFunc(a2),a0
  2345.     move.l    a0,p_PlayerHook(a3)
  2346.     move.l    h_Entry(a0),p_PlayerEntry(a3)
  2347.  
  2348.     btst    #PB_DMA,p_Flags(a3)
  2349.     beq    .no_dma
  2350.     bsr    DMA_Update
  2351.     bra    .exit
  2352.  
  2353. .no_dma
  2354.     move.l    ahiac_BuffSamples(a2),d1
  2355.     and.b    #~3,d1            ;make it a multiple of 4
  2356.     move.l    d1,ahiac_BuffSamples(a2)
  2357.     move.l    d1,d0
  2358.     lsr.l    #2,d0
  2359.     subq.l    #1,d0
  2360.     move.l    d0,p_LoopTimes(a3)    ;See softints. (Unrolled)
  2361.  
  2362.     move.l    ahiac_MixerFunc(a2),a0
  2363.     move.l    a0,p_MixHook(a3)
  2364.     move.l    h_Entry(a0),p_MixEntry(a3)
  2365.  
  2366. .exit
  2367.     call    AHIsub_Enable
  2368.     moveq    #0,d0
  2369.     popm    std
  2370.     rts
  2371.  
  2372.  
  2373. ****** [driver].audio/AHIsub_Stop *******************************************
  2374. *
  2375. *   NAME
  2376. *       AHIsub_Stop -- Stops playback.
  2377. *
  2378. *   SYNOPSIS
  2379. *       AHIsub_Stop( flags, audioctrl );
  2380. *                    D0     A2
  2381. *
  2382. *       void AHIsub_Stop( ULONG, struct AHIAudioCtrlDrv * );
  2383. *
  2384. *   IMPLEMENTATION
  2385. *       Stop playback and/or recording, remove all resources allocated by
  2386. *       AHIsub_Start().
  2387. *
  2388. *   INPUTS
  2389. *       flags - See <libraries/ahi_sub.h>.
  2390. *       audioctrl - pointer to an AHIAudioCtrlDrv structure.
  2391. *
  2392. *   NOTES
  2393. *       It must be safe to call this routine even if AHIsub_Start() was never
  2394. *       called, failed or called more than once.
  2395. *
  2396. *   SEE ALSO
  2397. *       AHIsub_Start()
  2398. *
  2399. *****************************************************************************
  2400. *
  2401. *
  2402.  
  2403. AHIsub_Stop:
  2404.     PRINTF    2,"AHIsub_Stop()"
  2405.     pushm    std
  2406.  
  2407.     lea    custom,a4
  2408.     move.l    a6,a5
  2409.     move.l    pb_SysLib(a5),a6
  2410.     move.l    ahiac_DriverData(a2),a3
  2411.  
  2412.     push    d0
  2413.     btst    #AHISB_PLAY,d0
  2414.     beq    .dontplay
  2415.  
  2416. **
  2417. *** AHISB_PLAY
  2418. **
  2419.  
  2420.     btst    #PB_DMA,p_Flags(a3)
  2421.     beq    .no_dma
  2422.     bsr    DMA_Stop
  2423.     bra    .playchecked
  2424. .no_dma
  2425.  
  2426.     move.w    #DMAF_AUDIO,DMACON(a4)        ;disable audio DMA
  2427.  
  2428.     and.w    #~INTF_AUD0,p_IRQMask(a3)
  2429.     move.w    #INTF_AUD0,INTENA(a4)
  2430.     move.w    #INTF_AUD0,INTREQ(a4)        ;Clear any waiting interrupts
  2431.     move.l    #Interrupt_Dummy,IS_CODE+p_PlayInt(a3)
  2432.     lea    p_PlayInt(a3),a1
  2433.     moveq    #INTB_AUD0,d0
  2434.     call    SetIntVector
  2435.  
  2436.     moveq    #0,d0
  2437.     move.w    d0,AUD0VOL(a4)
  2438.     move.w    d0,AUD1VOL(a4)
  2439.     move.w    d0,AUD2VOL(a4)
  2440.     move.w    d0,AUD3VOL(a4)
  2441.  
  2442.     move.l    p_DMAbuffer(a3),d0
  2443.     beq.b    .nodmamem
  2444.     move.l    d0,a1
  2445.     clr.l    p_DMAbuffer(a3)
  2446.     call    FreeVec
  2447. .nodmamem
  2448.     move.l    p_Mixbuffer(a3),d0
  2449.     beq.b    .nomixmem
  2450.     move.l    d0,a1
  2451.     clr.l    p_Mixbuffer(a3)
  2452.     call    FreeVec
  2453. .nomixmem
  2454. .playchecked
  2455.  
  2456. .dontplay
  2457.     pop    d0
  2458.     btst    #AHISB_RECORD,d0
  2459.     beq    .dontrecord
  2460.  
  2461. **
  2462. *** AHISB_RECORD
  2463. **
  2464.     btst    #PB_14BIT,p_Flags(a3)        ;Sanity check...
  2465.     bne    .dontrecord
  2466.  
  2467.     and.w    #~INTF_AUD3,p_IRQMask(a3)
  2468.     move.w    #INTF_AUD3,INTENA(a4)
  2469.     move.w    #INTF_AUD3,INTREQ(a4)        ;Clear any waiting interrupts
  2470.  
  2471.     move.l    #Interrupt_Dummy,IS_CODE+p_RecInt(a3)
  2472.     lea    p_RecInt(a3),a1
  2473.     moveq    #INTB_AUD3,d0
  2474.     call    SetIntVector
  2475.  
  2476.     move.w    #0,AUD2VOL(a4)
  2477.     move.w    #0,AUD3VOL(a4)
  2478.  
  2479.     move.l    p_RecBuffer1(a3),d0
  2480.     beq.b    .norecmem1
  2481.     move.l    d0,a1
  2482.     clr.l    p_RecBuffer1(a3)
  2483.     call    FreeVec
  2484. .norecmem1
  2485.     move.l    p_RecBuffer2(a3),d0
  2486.     beq.b    .norecmem2
  2487.     move.l    d0,a1
  2488.     clr.l    p_RecBuffer2(a3)
  2489.     call    FreeVec
  2490. .norecmem2
  2491. .dontrecord
  2492. .exit
  2493.     moveq    #0,d0
  2494.     popm    std
  2495.     rts
  2496.  
  2497.  
  2498. ****** [driver].audio/AHIsub_GetAttr ****************************************
  2499. *
  2500. *   NAME
  2501. *       AHIsub_GetAttr -- Returns information about audio modes or driver
  2502. *
  2503. *   SYNOPSIS
  2504. *       AHIsub_GetAttr( attribute, argument, default, taglist, audioctrl );
  2505. *       D0              D0         D1        D2       A1       A2
  2506. *
  2507. *       LONG AHIsub_GetAttr( ULONG, LONG, LONG, struct TagItem *,
  2508. *                            struct AHIAudioCtrlDrv * );
  2509. *
  2510. *   IMPLEMENTATION
  2511. *       Return the attribute based on a tag list and an AHIAudioCtrlDrv
  2512. *       structure, which are the same that will be passed to
  2513. *       AHIsub_AllocAudio() by 'ahi.device'. If the attribute is
  2514. *       unknown to you, return the default.
  2515. *
  2516. *   INPUTS
  2517. *       attribute - Is really a Tag and can be one of the following:
  2518. *
  2519. *           AHIDB_Bits - Return how many output bits the tag list will
  2520. *               result in.
  2521. *
  2522. *           AHIDB_MaxChannels - Return the maximum number of channels.
  2523. *
  2524. *           AHIDB_Frequencies - Return how many mixing/sampling frequencies
  2525. *               you support
  2526. *
  2527. *           AHIDB_Frequency - Return the argument:th frequency
  2528. *               Example: You support 3 frequencies; 32, 44.1 and 48 kHz.
  2529. *                   If argument is 1, return 44100.
  2530. *
  2531. *           AHIDB_Index - Return the index which gives the frequency closest
  2532. *               to argument.
  2533. *               Example: You support 3 frequencies; 32, 44.1 and 48 kHz.
  2534. *                   If argument is 40000, return 1 (=> 44100).
  2535. *
  2536. *           AHIDB_Author - Return pointer to name of driver author:
  2537. *               "Martin 'Leviticus' Blom"
  2538. *
  2539. *           AHIDB_Copyright - Return pointer to copyright notice, including
  2540. *               the '©' character: "© 1996 Martin Blom" or "Public Domain"
  2541. *
  2542. *           AHIDB_Version - Return pointer version string, normal Amiga
  2543. *               format: "paula 1.5 (18.2.96)\r\n"
  2544. *
  2545. *           AHIDB_Annotation - Return pointer to an annotation string, which
  2546. *               can be several lines.
  2547. *
  2548. *           AHIDB_Record - Are you a sampler, too? Return TRUE or FALSE.
  2549. *
  2550. *           AHIDB_FullDuplex - Return TRUE or FALSE.
  2551. *
  2552. *           AHIDB_Realtime - Return TRUE or FALSE.
  2553. *
  2554. *           AHIDB_MaxPlaySamples - Normally, return the default. See
  2555. *               AHIsub_AllocAudio(), section 2.
  2556. *
  2557. *           AHIDB_MaxRecordSamples - Return the size of the buffer you fill
  2558. *               when recording.
  2559. *
  2560. *           The following are associated with AHIsub_HardwareControl() and are
  2561. *           new for V2.
  2562. *
  2563. *           AHIDB_MinMonitorVolume
  2564. *           AHIDB_MaxMonitorVolume - Return the lower/upper limit for
  2565. *               AHIC_MonitorVolume. If unsupported but always 1.0, return
  2566. *               1.0 for both.
  2567. *
  2568. *           AHIDB_MinInputGain
  2569. *           AHIDB_MaxInputGain - Return the lower/upper limit for
  2570. *               AHIC_InputGain. If unsupported but always 1.0, return 1.0 for
  2571. *               both.
  2572. *
  2573. *           AHIDB_MinOutputVolume
  2574. *           AHIDB_MaxOutputVolume - Return the lower/upper limit for
  2575. *               AHIC_OutputVolume.
  2576. *
  2577. *           AHIDB_Inputs - Return how many inputs you have.
  2578. *           AHIDB_Input - Return a short string describing the argument:th
  2579. *               input. Number 0 should be the default one. Example strings
  2580. *               can be "Line 1", "Mic", "Optical" or whatever.
  2581. *
  2582. *           AHIDB_Outputs - Return how many outputs you have.
  2583. *           AHIDB_Output - Return a short string describing the argument:th
  2584. *               output. Number 0 should be the default one. Example strings
  2585. *               can be "Line 1", "Headphone", "Optical" or whatever.
  2586. *
  2587. *       argument - extra info for some attributes.
  2588. *       default - What you should return for unknown attributes.
  2589. *       taglist - Pointer to a tag list that eventually will be fed to
  2590. *           AHIsub_AllocAudio(), or NULL.
  2591. *       audioctrl - Pointer to an AHIAudioCtrlDrv structure that eventually
  2592. *           will be fed to AHIsub_AllocAudio(), or NULL.
  2593. *
  2594. *   NOTES
  2595. *
  2596. *   SEE ALSO
  2597. *       AHIsub_AllocAudio(), AHIsub_HardwareControl(),
  2598. *       ahi.device/AHI_GetAudioAttrsA()
  2599. *
  2600. *****************************************************************************
  2601. *
  2602. *
  2603.  
  2604. AHIsub_GetAttr:
  2605.     PRINTF    2,"AHIsub_GetAttr()"
  2606.     pushm    std
  2607.     move.l    a1,a3
  2608.     move.l    a6,a5
  2609.     move.l    pb_UtilLib(a5),a6
  2610.  
  2611.  
  2612.     moveq    #FALSE,d3        ; 14 bit flag
  2613.     moveq    #FALSE,d4        ; DMA flag
  2614.  
  2615.     pushm    d0-d1
  2616.  
  2617.     move.l    a3,a0
  2618.     move.l    a3,d0
  2619.     beq    .notaglist
  2620.  
  2621.     move.l    #AHIDB_Paula14Bit,d0
  2622.     move.l    d3,d1
  2623.     call    GetTagData
  2624.     move.l    d0,d3
  2625.  
  2626.     move.l    a3,a0
  2627.     move.l    #AHIDB_PaulaDMA,d0
  2628.     move.l    d4,d1
  2629.     call    GetTagData
  2630.     move.l    d0,d4
  2631.  
  2632. .notaglist
  2633.  
  2634.     popm    d0-d1
  2635.  
  2636.     and.l    #~(AHI_TagBaseR),d0
  2637.     cmp.l    #AHIDB_Data & ~(AHI_TagBaseR),d0
  2638.     bhi    .default
  2639.     sub.w    #100,d0
  2640.     lsl.w    #1,d0
  2641.     move.w    .jt(pc,d0.w),d0
  2642.     beq    .default
  2643.     jsr    .jt(pc,d0.w)
  2644.  
  2645. .exit
  2646.     popm    std
  2647.     rts
  2648.  
  2649. .default
  2650.     move.l    d2,d0
  2651.     bra    .exit
  2652.  
  2653. .jt
  2654.     dc.w    0                ; AHIDB_AudioID
  2655.     dc.w    0                ; AHIDB_Driver
  2656.     dc.w    0                ; AHIDB_Flags
  2657.     dc.w    ga_Volume-.jt            ; AHIDB_Volume
  2658.     dc.w    ga_Panning-.jt            ; AHIDB_Panning
  2659.     dc.w    ga_Stereo-.jt            ; AHIDB_Stereo
  2660.     dc.w    ga_HiFi-.jt            ; AHIDB_HiFi
  2661.     dc.w    ga_PingPong-.jt            ; AHIDB_PingPong
  2662.     dc.w    0                ; AHIDB_MultTable
  2663.     dc.w    0                ; AHIDB_Name
  2664.     dc.w    ga_Bits-.jt            ; AHIDB_Bits
  2665.     dc.w    ga_MaxChannels-.jt        ; AHIDB_MaxChannels
  2666.     dc.w    0                ; AHIDB_MinMixFreq
  2667.     dc.w    0                ; AHIDB_MaxMixFreq
  2668.     dc.w    ga_Record-.jt            ; AHIDB_Record
  2669.     dc.w    ga_Frequencies-.jt        ; AHIDB_Frequencies
  2670.     dc.w    0                ; AHIDB_FrequencyArg
  2671.     dc.w    ga_Frequency-.jt        ; AHIDB_Frequency
  2672.     dc.w    ga_Author-.jt            ; AHIDB_Author
  2673.     dc.w    ga_Copyright-.jt        ; AHIDB_Copyright
  2674.     dc.w    ga_Version-.jt            ; AHIDB_Version
  2675.     dc.w    ga_Annotation-.jt        ; AHIDB_Annotation
  2676.     dc.w    0                ; AHIDB_BufferLen
  2677.     dc.w    0                ; AHIDB_IndexArg
  2678.     dc.w    ga_Index-.jt            ; AHIDB_Index
  2679.     dc.w    ga_Realtime-.jt            ; AHIDB_Realtime
  2680.     dc.w    0                ; AHIDB_MaxPlaySamples
  2681.     dc.w    ga_MaxRecordSamples-.jt        ; AHIDB_MaxRecordSample
  2682.     dc.w    0                ; 
  2683.     dc.w    ga_FullDuplex-.jt        ; AHIDB_FullDuplex
  2684.     dc.w    ga_MinMonitorVolume-.jt        ; AHIDB_MinMonitorVolum
  2685.     dc.w    ga_MaxMonitorVolume-.jt        ; AHIDB_MaxMonitorVolum
  2686.     dc.w    ga_MinInputGain-.jt        ; AHIDB_MinInputGain
  2687.     dc.w    ga_MaxInputGain-.jt        ; AHIDB_MaxInputGain
  2688.     dc.w    ga_MinOutputVolume-.jt        ; AHIDB_MinOutputVolume
  2689.     dc.w    ga_MaxOutputVolume-.jt        ; AHIDB_MaxOutputVolume
  2690.     dc.w    ga_Inputs-.jt            ; AHIDB_Inputs
  2691.     dc.w    0                ; AHIDB_InputArg
  2692.     dc.w    ga_Input-.jt            ; AHIDB_Input
  2693.     dc.w    ga_Outputs-.jt            ; AHIDB_Outputs
  2694.     dc.w    0                ; AHIDB_OutputArg
  2695.     dc.w    ga_Output-.jt            ; AHIDB_Output
  2696.     dc.w    0                ; AHIDB_Data
  2697.  
  2698.  
  2699. *** The tags AHIDB_Volume, AHIDB_Panning, AHIDB_Stereo and AHIDB_HiFi are
  2700. *** parameters to the mixing routine when mixing, but attributes in DMA mode.
  2701.  
  2702. ga_Volume:
  2703.     move.l    d2,d0
  2704.     tst.l    d4
  2705.     beq    .exit
  2706.     moveq    #TRUE,d0
  2707. .exit
  2708.     rts
  2709.  
  2710. ga_Panning:
  2711.     move.l    d2,d0
  2712.     tst.l    d4
  2713.     beq    .exit
  2714.     moveq    #FALSE,d0
  2715. .exit
  2716.     rts
  2717.  
  2718. ga_Stereo:
  2719.     move.l    d2,d0
  2720.     tst.l    d4
  2721.     beq    .exit
  2722.     moveq    #TRUE,d0
  2723. .exit
  2724.     rts
  2725.  
  2726. ga_HiFi:
  2727.     move.l    d2,d0
  2728.     tst.l    d4
  2729.     beq    .exit
  2730.     moveq    #TRUE,d0
  2731. .exit
  2732.     rts
  2733.  
  2734. ga_PingPong:
  2735.     move.l    d2,d0
  2736.     tst.l    d4
  2737.     beq    .exit
  2738.     moveq    #TRUE,d0
  2739. .exit
  2740.     rts
  2741.  
  2742. ga_Bits:
  2743.     moveq    #14,d0
  2744.     tst.l    d3
  2745.     bne    .exit
  2746.     moveq    #8,d0
  2747. .exit
  2748.     rts
  2749.  
  2750. ga_MaxChannels:
  2751.     moveq    #4,d0
  2752.     tst.l    d4
  2753.     bne    .exit
  2754.     move.l    d2,d0
  2755. .exit
  2756.     rts
  2757.  
  2758. ga_Record:
  2759.     moveq    #FALSE,d0
  2760.     tst.l    d3
  2761.     bne    .exit
  2762.     tst.l    d4
  2763.     bne    .exit
  2764.     moveq    #TRUE,d0
  2765. .exit
  2766.     rts
  2767.  
  2768. ga_Frequencies:
  2769.     moveq    #1,d0
  2770.     tst.l    d4
  2771.     bne    .exit
  2772.     bsr    checkvideo
  2773.     tst.l    d0
  2774.     beq    .1
  2775.     moveq    #FREQUENCIES,d0
  2776. .exit
  2777.     rts
  2778. .1
  2779.     moveq    #FREQUENCIES_OCS,d0
  2780.     rts
  2781.  
  2782. ga_Frequency:
  2783.     tst.l    d4
  2784.     beq    .nodma
  2785.     move.l    #PALFREQ,d2            ;PAL
  2786.     move.l    pb_GfxLib(a5),a0
  2787.     move.w    gb_DisplayFlags(a0),d0
  2788.     btst    #REALLY_PALn,d0
  2789.     bne.b    .1
  2790.     move.l    #NTSCFREQ,d2            ;NTSC
  2791. .1
  2792.     move.l    d2,d0
  2793.     rts
  2794. .nodma
  2795.     lsl.w    #2,d1
  2796.     lea    freqlist(pc),a0
  2797.     move.l    (a0,d1.w),d0
  2798.     rts
  2799.  
  2800. ga_Author:
  2801.     lea    .author(pc),a0
  2802.     move.l    a0,d0
  2803.     rts
  2804. .author        dc.b    "Martin 'Leviticus' Blom",0
  2805.     even
  2806.  
  2807. ga_Copyright:
  2808.     lea    .copyright(pc),a0
  2809.     move.l    a0,d0
  2810.     rts
  2811. .copyright    dc.b    "Public Domain",0
  2812.     even
  2813.  
  2814. ga_Version:
  2815.     lea    IDString(pc),a0
  2816.     move.l    a0,d0
  2817.     rts
  2818.  
  2819. ga_Annotation:
  2820.     lea    .anno(pc),a0
  2821.     move.l    a0,d0
  2822.     rts
  2823. .anno        dc.b    "14 bit routines by Christian Buchner.",0
  2824.     even
  2825.  
  2826. ga_Index:
  2827.     move.l    d1,d0
  2828.     bsr    findfreq
  2829.     move.l    d1,d0
  2830.     rts
  2831.  
  2832.  
  2833. ga_Realtime:
  2834.     moveq    #TRUE,d0
  2835.     rts
  2836.  
  2837. ga_MaxRecordSamples:
  2838.     move.l    #RECORDSAMPLES,d0
  2839.     rts
  2840.  
  2841. ga_FullDuplex:
  2842.     moveq    #FALSE,d0
  2843.     tst.l    d3
  2844.     bne    .exit
  2845.     tst.l    d4
  2846.     bne    .exit
  2847.     moveq    #TRUE,d0
  2848. .exit
  2849.     rts
  2850.  
  2851.  
  2852. ga_MinMonitorVolume:
  2853.     moveq    #0,d0
  2854.     rts
  2855.  
  2856. ga_MaxMonitorVolume:
  2857.     moveq    #0,d0
  2858.     tst.l    d3
  2859.     bne    .exit
  2860.     tst.l    d4
  2861.     bne    .exit
  2862.     move.l    #$10000,d0
  2863. .exit
  2864.     rts
  2865.  
  2866. ga_MinInputGain:
  2867.     move.l    #$10000,d0
  2868.     rts
  2869.  
  2870. ga_MaxInputGain:
  2871.     move.l    #$10000,d0
  2872.     rts
  2873.  
  2874. ga_MinOutputVolume:
  2875.     move.l    #$10000,d0
  2876.     tst.l    d3
  2877.     bne    .exit
  2878.     tst.l    d4
  2879.     bne    .exit
  2880.     moveq    #0,d0
  2881. .exit
  2882.     rts
  2883.  
  2884. ga_MaxOutputVolume:
  2885.     move.l    #$10000,d0
  2886.     rts
  2887.  
  2888.  
  2889. ga_Inputs:
  2890.     moveq    #0,d0
  2891.     tst.l    d3
  2892.     bne    .exit
  2893.     tst.l    d4
  2894.     bne    .exit
  2895.     moveq    #3,d0
  2896. .exit
  2897.     rts
  2898.  
  2899. ga_Input:
  2900.     lsl.l    #2,d1
  2901.     move.l    .inputs(pc,d1.w),d0
  2902.     rts
  2903. .inputs        dc.l    .input0
  2904.         dc.l    .input1
  2905.         dc.l    .input2
  2906.  
  2907. .input0        dc.b    "Parallel port sampler",0
  2908. .input1        dc.b    "Aura sampler",0
  2909. .input2        dc.b    "Clarity sampler",0
  2910.     even
  2911.  
  2912. ga_Outputs:
  2913.     moveq    #1,d0
  2914.     rts
  2915.  
  2916. ga_Output:
  2917.     lea    .output(pc),a0
  2918.     move.l    a0,d0
  2919.     rts
  2920. .output        dc.b    "Line",0
  2921.     even
  2922.  
  2923.  
  2924. ****** [driver].audio/AHIsub_HardwareControl ********************************
  2925. *
  2926. *   NAME
  2927. *       AHIsub_HardwareControl -- Modify sound card settings
  2928. *
  2929. *   SYNOPSIS
  2930. *       AHIsub_HardwareControl( attribute,  argument, audioctrl );
  2931. *       D0                      D0          D1        A2
  2932. *
  2933. *       LONG AHIsub_HardwareControl( ULONG, LONG, struct AHIAudioCtrlDrv * );
  2934. *
  2935. *   IMPLEMENTATION
  2936. *       Set or return the state of a particular hardware component. AHI uses
  2937. *       AHIsub_GetAttr() to supply the user with limits and what tags are
  2938. *       available.
  2939. *
  2940. *   INPUTS
  2941. *       attribute - Is really a Tag and can be one of the following:
  2942. *
  2943. *           AHIC_MonitorVolume - Set the input monitor volume to argument.
  2944. *           AHIC_MonitorVolume_Query - Return the current input monitor
  2945. *               volume (argument is ignored).
  2946. *
  2947. *           AHIC_InputGain - Set the input gain to argument. (V2)
  2948. *           AHIC_InputGain_Query (V2)
  2949. *
  2950. *           AHIC_OutputVolume - Set the output volume to argument. (V2)
  2951. *           AHIC_OutputVolume_Query (V2)
  2952. *
  2953. *           AHIC_Input - Use the argument:th input source (default is 0). (V2)
  2954. *           AHIC_Input_Query (V2)
  2955. *
  2956. *           AHIC_Output - Use the argument:th output destination (default
  2957. *               is 0). (V2)
  2958. *           AHIC_Output_Query (V2)
  2959. *
  2960. *       argument - What value attribute should be set to.
  2961. *       audioctrl - Pointer to an AHIAudioCtrlDrv structure.
  2962. *
  2963. *   RESULT
  2964. *       Return the state of selected attribute. If you were asked to set
  2965. *       something, return TRUE. If attribute is unknown to you or unsupported,
  2966. *       return FALSE.
  2967. *
  2968. *   NOTES
  2969. *       This call must be safe from interrupts.
  2970. *
  2971. *   SEE ALSO
  2972. *       ahi.device/AHI_ControlAudioA(), AHIsub_GetAttr()
  2973. *
  2974. *****************************************************************************
  2975. *
  2976. *
  2977.  
  2978. AHIsub_HardwareControl:
  2979.     PRINTF    2,"AHIsub_HardwareControl()"
  2980.     cmp.l    #AHIC_MonitorVolume,d0
  2981.     bne.b    .dontsetmonvol
  2982.     move.l    ahiac_DriverData(a2),a1
  2983.     lsr.l    #8,d1
  2984.     lsr.l    #2,d1
  2985.     move.w    d1,p_MonitorVolume(a1)
  2986.     bra.b    .exit
  2987. .dontsetmonvol
  2988.     cmp.l    #AHIC_MonitorVolume_Query,d0
  2989.     bne.b    .dontgetmonvol
  2990.     move.l    ahiac_DriverData(a2),a1
  2991.     moveq    #0,d0
  2992.     move.w    p_MonitorVolume(a1),d0
  2993.     lsl.l    #8,d0
  2994.     lsl.l    #2,d0
  2995.     bra.b    .quit
  2996. .dontgetmonvol
  2997.     cmp.l    #AHIC_OutputVolume,d0
  2998.     bne.b    .dontsetoutvol
  2999.     move.l    ahiac_DriverData(a2),a1
  3000.     lsr.l    #8,d1
  3001.     lsr.l    #2,d1
  3002.     move.w    d1,p_OutputVolume(a1)
  3003.     bra.b    .exit
  3004. .dontsetoutvol
  3005.     cmp.l    #AHIC_OutputVolume_Query,d0
  3006.     bne.b    .dontgetoutvol
  3007.     move.l    ahiac_DriverData(a2),a1
  3008.     moveq    #0,d0
  3009.     move.w    p_OutputVolume(a1),d0
  3010.     lsl.l    #8,d0
  3011.     lsl.l    #2,d0
  3012.     bra.b    .quit
  3013. .dontgetoutvol
  3014.     cmp.l    #AHIC_Input,d0
  3015.     bne.b    .dontsetinput
  3016.     move.l    ahiac_DriverData(a2),a1
  3017.     move.w    d1,p_Input(a1)
  3018.     bra.b    .exit
  3019. .dontsetinput
  3020.     cmp.l    #AHIC_Input_Query,d0
  3021.     bne.b    .dontgetinput
  3022.     move.l    ahiac_DriverData(a2),a1
  3023.     moveq    #0,d0
  3024.     move.w    p_Input(a1),d0
  3025.     bra.b    .quit
  3026. .dontgetinput
  3027.     moveq    #FALSE,d0
  3028. .quit
  3029.     rts
  3030. .exit
  3031.     moveq    #TRUE,d0
  3032.     rts
  3033.  
  3034.  
  3035.  
  3036.  
  3037.  
  3038.  
  3039.  
  3040. *******************************************************************************
  3041. ***** Interrupt routines ******************************************************
  3042. *******************************************************************************
  3043.  
  3044. Interrupt_Dummy:
  3045.     move.w    #INTF_AUDIO,INTREQ(a0)
  3046. SoftInt_Dummy:
  3047.     rts
  3048.  
  3049. ;in:
  3050. * d0    scratch
  3051. * d1    INTENAR & INTREQR
  3052. * a0    custom
  3053. * a1    &(paula->p_RecIntData)
  3054. * a5    &RecordInterrupt
  3055. * a6    ExecBase
  3056. RecordInterrupt:
  3057.  
  3058. * This function will be executed up to 28000 times per second - that's once per
  3059. * rasterline! It has to be as fast as possible.
  3060.  
  3061.     move.w    #INTF_AUD2|INTF_AUD3,INTREQ(a0)    ;Clear the interrupt flags
  3062.     moveq    #0,d0
  3063.     move.b    _ciaa+ciaprb,d0            ;read parallel port
  3064.  IFGE    __CPU-68020
  3065.     move.l    convtable(pc,d0.w*4),d0        ;1 unsigned byte -> 2 signed words
  3066.  ELSE
  3067.     add.w    d0,d0
  3068.     add.w    d0,d0
  3069.     move.l    convtable(pc,d0.w),d0
  3070.  ENDC
  3071.     move.w    d0,AUD2DAT(a0)            ;left
  3072.     move.w    d0,AUD3DAT(a0)            ;right
  3073.  
  3074.     move.l    (a1),a5                ;p_RecFillPtr
  3075.     move.l    d0,(a5)+            ;store sample in buffer
  3076.     move.l    a5,(a1)+            ;update pointer
  3077.     subq.w    #1,(a1)                ;p_ReqFillCount
  3078.     beq    ri_Filled            ;branch if buffer filled
  3079.     rts
  3080.  
  3081. convtable
  3082. CNT    SET    0
  3083.     REPT    256
  3084.     dc.b    CNT-128,CNT-128,CNT-128,CNT-128
  3085. CNT    SET    CNT+1
  3086.     ENDR
  3087.  
  3088. ;in:
  3089. * d0    scratch
  3090. * d1    INTENAR & INTREQR
  3091. * a0    custom
  3092. * a1    &(paula->p_RecIntData)
  3093. * a5    &RecordInterrupt
  3094. * a6    ExecBase
  3095. RecordInterruptClarity:
  3096.  
  3097. * This function will be executed up to 28000 times per second - that's once per
  3098. * rasterline! It has to be as fast as possible.
  3099.  
  3100.     move.w    #INTF_AUD2|INTF_AUD3,INTREQ(a0)    ;Clear the interrupt flags
  3101.  
  3102.     lea    _ciab+ciatahi,a5
  3103.  
  3104.     move.b    _ciaa+ciaprb,d0            ;left lsb
  3105.     ror.l    #8,d0                ;d0: L0xxxxxx
  3106.     tst.b    (a5)                ;3x700 kHz wait states
  3107.     tst.b    (a5)
  3108.     tst.b    (a5)
  3109.  
  3110.     move.b    _ciaa+ciaprb,d0            ;left msb
  3111.     ror.l    #8,d0                ;d0: L1L0xxxx
  3112.     tst.b    (a5)                ;3x700 kHz wait states
  3113.     tst.b    (a5)
  3114.     tst.b    (a5)
  3115.  
  3116.     move.b    _ciaa+ciaprb,d0            ;right lsb
  3117.     lsl.w    #8,d0                ;d0: L1L0R0xx
  3118.     tst.b    (a5)                ;3x700 kHz wait states
  3119.     tst.b    (a5)
  3120.     tst.b    (a5)
  3121.  
  3122.     move.b    _ciaa+ciaprb,d0            ;right msb
  3123.     ror.w    #8,d0                ;d0: L1L0R1R0
  3124.  
  3125.     move.l    (a1),a5                ;p_RecFillPtr
  3126.     move.l    d0,(a5)+            ;store sample in buffer
  3127.     move.l    a5,(a1)+            ;update pointer
  3128.  
  3129.     move.w    d0,d1
  3130.     lsr.w    #8,d0
  3131.     move.b    d0,d1
  3132.  
  3133.     move.w    d1,AUD2DAT(a0)            ;right
  3134.     move.w    d1,AUD3DAT(a0)            ;left
  3135.  
  3136.     subq.w    #1,(a1)                ;p_ReqFillCount
  3137.     beq    ri_Filled            ;branch if buffer filled
  3138.     rts
  3139.  
  3140. ;in:
  3141. * d0    scratch
  3142. * d1    INTENAR & INTREQR
  3143. * a0    custom
  3144. * a1    &(paula->p_RecIntDataAura)
  3145. * a5    &RecordInterrupt
  3146. * a6    ExecBase
  3147. RecordInterruptAura:
  3148.  
  3149. * This function will be executed up to 28000 times per second - that's once per
  3150. * rasterline! It has to be as fast as possible.
  3151.  
  3152.     move.w    #INTF_AUD2|INTF_AUD3,INTREQ(a0)    ;Clear the interrupt flags
  3153.     move.l    (a1)+,a5
  3154.     move.l    (a5),d0                ;read aura sampler
  3155.     eor.l    #$80008000,d0
  3156.     move.l    (a1),a5                ;p_RecFillPtr
  3157.     move.l    d0,(a5)+            ;store sample in buffer
  3158.     move.l    a5,(a1)+            ;update pointer
  3159.  
  3160.     move.w    d0,d1
  3161.     lsr.w    #8,d0
  3162.     move.b    d0,d1
  3163.  
  3164.     move.w    d1,AUD2DAT(a0)            ;left
  3165.     move.w    d1,AUD3DAT(a0)            ;right
  3166.  
  3167.     subq.w    #1,(a1)                ;p_ReqFillCount
  3168.     beq    ri_Filled            ;branch if buffer filled
  3169.     rts
  3170.  
  3171. *******************************************************************************
  3172.  
  3173. ri_Filled:
  3174.  
  3175. * This part is only executed every RECORDSAMPLES:th time... No need to hurry.
  3176.  
  3177.     move.l    8(a1),d0            ;p_RecBuffer2->
  3178.     move.l    4(a1),8(a1)            ;p_RecBuffer1->p_RecBuffer2
  3179.     move.l    d0,4(a1)            ;            ->p_RecBuffer1
  3180.     move.l    d0,-4(a1)            ;p_RecFillPtr
  3181.     move.w    #RECORDSAMPLES,(a1)        ;p_ReqFillCount
  3182.     move.l    12(a1),a1            ;p_RecSoftIntPtr
  3183.     jmp    _LVOCause(a6)
  3184.  
  3185.  
  3186. ;in:
  3187. * d0    scratch
  3188. * d1    scratch
  3189. * a0    scratch
  3190. * a1    struct paula *
  3191. * a5    scratch
  3192. RecordSoftInt:
  3193.  
  3194. * This function is not executed many times per second and is therefore not
  3195. * fully optimized... ;)
  3196.     push    a2
  3197.     move.w    p_MonitorVolume(a1),d0
  3198.     move.w    d0,custom+AUD2VOL
  3199.     move.w    d0,custom+AUD3VOL
  3200.     move.l    p_RecBuffer2(a1),p_rmBuffer(a1)
  3201.     move.l    p_AudioCtrl(a1),a2
  3202.     lea    p_RecordMessage(a1),a1
  3203.     move.l    ahiac_SamplerFunc(a2),a0
  3204.     move.l    h_Entry(a0),a5
  3205.     jsr    (a5)
  3206.     pop    a2
  3207.     rts
  3208.  
  3209. *******************************************************************************
  3210. *******************************************************************************
  3211.  
  3212. ;in:
  3213. * d0    scratch
  3214. * d1    INTENAR & INTREQR
  3215. * a0    custom
  3216. * a1    struct paula *
  3217. * a5    &AudioInterrupt
  3218. * a6    ExecBase
  3219.  
  3220. AudioInterrupt2:                ;Two hardware channels used
  3221. ;    move.l    p_AudLenPer(a1),d0
  3222. ;    move.l    d0,AUD0LEN(a0)
  3223. ;    move.l    d0,AUD1LEN(a0)
  3224.     move.w    p_AudPer(a1),d0
  3225.     move.w    d0,AUD0PER(a0)
  3226.     move.w    d0,AUD1PER(a0)
  3227.     move.w    p_OutputVolume(a1),AUD0VOL(a0)
  3228.     move.w    p_OutputVolume(a1),AUD1VOL(a0)
  3229.  
  3230.     move.l    p_DoubleBufferOffset(a1),d0
  3231.     eor.w    #4*4,d0
  3232.     move.l    d0,p_DoubleBufferOffset(a1)
  3233.  
  3234.     lea    p_AudPtrs(a1,d0.l),a5
  3235.     tst.w    p_SwapChannels(a1)
  3236.     bne    .swap
  3237.     move.l    (a5)+,AUD0LC(a0)
  3238.     move.l    (a5)+,AUD1LC(a0)
  3239.     bra    .1
  3240. .swap
  3241.     move.l    (a5)+,AUD1LC(a0)
  3242.     move.l    (a5)+,AUD0LC(a0)
  3243. .1
  3244.     lea    p_PlaySoftInt(a1),a1
  3245.     move.w    #INTF_AUD0,INTREQ(a0)        ;Clear the interrupt 
  3246.     jmp    _LVOCause(a6)            ;start PlaySoftInt
  3247.  
  3248.  
  3249. AudioInterrupt4:                ;Four hardware channels used
  3250. ;    move.l    p_AudLenPer(a1),d0
  3251. ;    move.l    d0,AUD0LEN(a0)
  3252. ;    move.l    d0,AUD1LEN(a0)
  3253. ;    move.l    d0,AUD2LEN(a0)
  3254. ;    move.l    d0,AUD3LEN(a0)
  3255.     move.w    p_AudPer(a1),d0
  3256.     move.w    d0,AUD0PER(a0)
  3257.     move.w    d0,AUD1PER(a0)
  3258.     move.w    d0,AUD2PER(a0)
  3259.     move.w    d0,AUD3PER(a0)
  3260.     move.w    #64,AUD0VOL(a0)
  3261.     move.w    #64,AUD1VOL(a0)
  3262.     move.w    #1,AUD2VOL(a0)
  3263.     move.w    #1,AUD3VOL(a0)
  3264.  
  3265.     move.l    p_DoubleBufferOffset(a1),d0
  3266.     eor.w    #4*4,d0
  3267.     move.l    d0,p_DoubleBufferOffset(a1)
  3268.  
  3269.     lea    p_AudPtrs(a1,d0.l),a5
  3270.     tst.w    p_SwapChannels(a1)
  3271.     bne    .swap
  3272.     move.l    (a5)+,AUD0LC(a0)
  3273.     move.l    (a5)+,AUD1LC(a0)
  3274.     move.l    (a5)+,AUD2LC(a0)
  3275.     move.l    (a5)+,AUD3LC(a0)
  3276.     bra    .1
  3277. .swap
  3278.     move.l    (a5)+,AUD1LC(a0)
  3279.     move.l    (a5)+,AUD0LC(a0)
  3280.     move.l    (a5)+,AUD3LC(a0)
  3281.     move.l    (a5)+,AUD2LC(a0)
  3282. .1
  3283.     lea    p_PlaySoftInt(a1),a1
  3284.     move.w    #INTF_AUD0,INTREQ(a0)        ;Clear the interrupt 
  3285.     jmp    _LVOCause(a6)            ;start PlaySoftInt
  3286.  
  3287.  
  3288. *******************************************************************************
  3289.  
  3290. ;in:
  3291. * d0    scratch
  3292. * d1    scratch
  3293. * a0    scratch
  3294. * a1    struct paula *
  3295. * a5    scratch
  3296.  
  3297. CONVERT_PRE    MACRO
  3298.     pushm    std
  3299.     move.l    a1,a6
  3300.     move.l    p_AudioCtrl(a6),a2
  3301.     move.l    ahiac_PreTimer(a2),a0
  3302.     jsr    (a0)
  3303.     move.l    d0,d7
  3304.  
  3305.     move.l    p_DoubleBufferOffset(a6),d0
  3306.     lea    p_AudPtrs(a6,d0.l),a0
  3307.     movem.l    (a0)+,d2/d3/d4/d5        ;get all 4 buffer pointers
  3308.  
  3309.     moveq    #0,d6
  3310. .repeat
  3311.     movem.l    p_PlayerHookRegs(a6),a0/a1/a3
  3312.     jsr    (a3)                ;call Player Hook
  3313.     tst.l    d7
  3314.     bne    .skip
  3315.     movem.l    p_MixHookRegs(a6),a0/a1/a3
  3316.     jsr    (a3)                ;call Mixer Hook
  3317.     move.l    p_LoopTimes(a6),d0
  3318.     ENDM
  3319.  
  3320. ;
  3321. ; Conversion code here!
  3322. ;
  3323. ; d0    counter
  3324. ; d1    scratch
  3325. ; d2-d5    buffer pointers
  3326. ; d6    (sample counter/4)
  3327. ; d7    (pretimer flag)
  3328. ; a0    scratch
  3329. ; a1    source buffer
  3330. ; a2    AudioCtrl
  3331. ; a3-a5    scratch
  3332. ; a6    struct paula *
  3333. ;
  3334. ; Conversion code here!
  3335. ;
  3336.  
  3337. CONVERT_POST    MACRO
  3338. .skip
  3339.     add.l    ahiac_BuffSamples(a2),d6
  3340.     cmp.l    p_MinBufferLength(a6),d6
  3341.     blo    .repeat
  3342.     move.l    ahiac_PostTimer(a2),a0
  3343.     jsr    (a0)
  3344.     move.l    d6,d0
  3345.     lea    custom,a0
  3346.     popm    std
  3347.     ENDM
  3348.  
  3349. ; Exit code here
  3350. ; d0    Samples in buffer
  3351. ; a0    custom
  3352.  
  3353. *******************************************************************************
  3354.  
  3355. SoftInt_8bitM:
  3356.  
  3357.     CONVERT_PRE
  3358.  
  3359.     move.l    d2,a0                ;get buffer ptr
  3360. .loop
  3361.     move.b    (a1),d1
  3362.     lsl.l    #8,d1
  3363.     move.b    2(a1),d1
  3364.     lsl.l    #8,d1
  3365.     move.b    4(a1),d1
  3366.     lsl.l    #8,d1
  3367.     move.b    6(a1),d1
  3368.     move.l    d1,(a0)+
  3369.     addq.w    #8,a1
  3370.     dbf    d0,.loop
  3371.     move.l    a0,d2                ;save buffer ptr
  3372.  
  3373.     CONVERT_POST
  3374.  
  3375.     lsr.l    #1,d0
  3376.     move.w    d0,AUD0LEN(a0)
  3377.     move.w    d0,AUD1LEN(a0)
  3378.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1,DMACON(a0)
  3379.     rts
  3380.  
  3381. *******************************************************************************
  3382.  
  3383. SoftInt_8bitMH:
  3384.     CONVERT_PRE
  3385.  
  3386.     move.l    d2,a0                ;get buffer ptr
  3387. .loop
  3388.     move.b    (a1),d1
  3389.     lsl.l    #8,d1
  3390.     move.b    4(a1),d1
  3391.     lsl.l    #8,d1
  3392.     move.b    8(a1),d1
  3393.     lsl.l    #8,d1
  3394.     move.b    12(a1),d1
  3395.     move.l    d1,(a0)+
  3396.     add.w    #16,a1
  3397.     dbf    d0,.loop
  3398.     move.l    a0,d2                ;save buffer ptr
  3399.  
  3400.     CONVERT_POST
  3401.  
  3402.     lsr.l    #1,d0
  3403.     move.w    d0,AUD0LEN(a0)
  3404.     move.w    d0,AUD1LEN(a0)
  3405.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1,DMACON(a0)
  3406.     rts
  3407.  
  3408. *******************************************************************************
  3409.  
  3410. SoftInt_8bitS:
  3411.     CONVERT_PRE
  3412.  
  3413.     move.l    d2,a0                ;get buffer ptr
  3414.     move.l    d3,a3                ;get buffer ptr
  3415. .loop
  3416.  
  3417. ; Left
  3418.     move.b    (a1),d1
  3419.     lsl.l    #8,d1
  3420.     move.b    4(a1),d1
  3421.     lsl.l    #8,d1
  3422.     move.b    8(a1),d1
  3423.     lsl.l    #8,d1
  3424.     move.b    12(a1),d1
  3425.     move.l    d1,(a3)+
  3426.  
  3427. ; Right
  3428.     move.b    2(a1),d1
  3429.     lsl.l    #8,d1
  3430.     move.b    6(a1),d1
  3431.     lsl.l    #8,d1
  3432.     move.b    10(a1),d1
  3433.     lsl.l    #8,d1
  3434.     move.b    14(a1),d1
  3435.     move.l    d1,(a0)+
  3436.  
  3437.     add.w    #16,a1
  3438.     dbf    d0,.loop
  3439.     move.l    a0,d2                ;save buffer ptr
  3440.     move.l    a3,d3                ;save buffer ptr
  3441.  
  3442.     CONVERT_POST
  3443.  
  3444.     lsr.l    #1,d0
  3445.     move.w    d0,AUD0LEN(a0)
  3446.     move.w    d0,AUD1LEN(a0)
  3447.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1,DMACON(a0)
  3448.     rts
  3449.  
  3450. *******************************************************************************
  3451.  
  3452. SoftInt_8bitSH:
  3453.     CONVERT_PRE
  3454.  
  3455.     move.l    d2,a0                ;get buffer ptr
  3456.     move.l    d3,a3                ;get buffer ptr
  3457. .loop
  3458.  
  3459. ; Left
  3460.     move.b    (a1),d1
  3461.     lsl.l    #8,d1
  3462.     move.b    8(a1),d1
  3463.     lsl.l    #8,d1
  3464.     move.b    16(a1),d1
  3465.     lsl.l    #8,d1
  3466.     move.b    24(a1),d1
  3467.     move.l    d1,(a3)+
  3468.  
  3469. ; Right
  3470.     move.b    4(a1),d1
  3471.     lsl.l    #8,d1
  3472.     move.b    12(a1),d1
  3473.     lsl.l    #8,d1
  3474.     move.b    20(a1),d1
  3475.     lsl.l    #8,d1
  3476.     move.b    28(a1),d1
  3477.     move.l    d1,(a0)+
  3478.  
  3479.     add.w    #32,a1
  3480.     dbf    d0,.loop
  3481.     move.l    a0,d2                ;save buffer ptr
  3482.     move.l    a3,d3                ;save buffer ptr
  3483.  
  3484.     CONVERT_POST
  3485.  
  3486.     lsr.l    #1,d0
  3487.     move.w    d0,AUD0LEN(a0)
  3488.     move.w    d0,AUD1LEN(a0)
  3489.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1,DMACON(a0)
  3490.     rts
  3491.  
  3492. *******************************************************************************
  3493.  
  3494. SoftInt_14bitM:
  3495.     CONVERT_PRE
  3496.  
  3497.     move.l    d2,a0                ;get buffer ptr
  3498.     move.l    d5,a5                ;get buffer ptr
  3499. .loop
  3500.  
  3501. ; High
  3502.     move.b    (a1),d1
  3503.     lsl.l    #8,d1
  3504.     move.b    2(a1),d1
  3505.     lsl.l    #8,d1
  3506.     move.b    4(a1),d1
  3507.     lsl.l    #8,d1
  3508.     move.b    6(a1),d1
  3509.     move.l    d1,(a0)+
  3510.  
  3511. ; Low
  3512.     move.b    1(a1),d1
  3513.     lsr.b    #2,d1
  3514.     lsl.l    #8,d1
  3515.     move.b    3(a1),d1
  3516.     lsr.b    #2,d1
  3517.     lsl.l    #8,d1
  3518.     move.b    5(a1),d1
  3519.     lsr.b    #2,d1
  3520.     lsl.l    #8,d1
  3521.     move.b    7(a1),d1
  3522.     lsr.b    #2,d1
  3523.     move.l    d1,(a5)+
  3524.  
  3525.     addq.w    #8,a1
  3526.     dbf    d0,.loop
  3527.     move.l    a0,d2                ;save buffer ptr
  3528.     move.l    a5,d5                ;save buffer ptr
  3529.  
  3530.     CONVERT_POST
  3531.  
  3532.     lsr.l    #1,d0
  3533.     move.w    d0,AUD0LEN(a0)
  3534.     move.w    d0,AUD1LEN(a0)
  3535.     move.w    d0,AUD2LEN(a0)
  3536.     move.w    d0,AUD3LEN(a0)
  3537.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,DMACON(a0)
  3538.     rts
  3539.  
  3540. *******************************************************************************
  3541.  
  3542.  
  3543. SoftInt_14bitMH:
  3544.     CONVERT_PRE
  3545.  
  3546.     move.l    d2,a0                ;get buffer ptr
  3547.     move.l    d5,a5                ;get buffer ptr
  3548. .loop
  3549.  
  3550. ; High
  3551.     move.b    (a1),d1
  3552.     lsl.l    #8,d1
  3553.     move.b    4(a1),d1
  3554.     lsl.l    #8,d1
  3555.     move.b    8(a1),d1
  3556.     lsl.l    #8,d1
  3557.     move.b    12(a1),d1
  3558.     move.l    d1,(a0)+
  3559.  
  3560. ; Low
  3561.     move.b    1(a1),d1
  3562.     lsr.b    #2,d1
  3563.     lsl.l    #8,d1
  3564.     move.b    5(a1),d1
  3565.     lsr.b    #2,d1
  3566.     lsl.l    #8,d1
  3567.     move.b    9(a1),d1
  3568.     lsr.b    #2,d1
  3569.     lsl.l    #8,d1
  3570.     move.b    13(a1),d1
  3571.     lsr.b    #2,d1
  3572.     move.l    d1,(a5)+
  3573.  
  3574.     add.w    #16,a1
  3575.     dbf    d0,.loop
  3576.     move.l    a0,d2                ;save buffer ptr
  3577.     move.l    a5,d5                ;save buffer ptr
  3578.  
  3579.     CONVERT_POST
  3580.  
  3581.     lsr.l    #1,d0
  3582.     move.w    d0,AUD0LEN(a0)
  3583.     move.w    d0,AUD1LEN(a0)
  3584.     move.w    d0,AUD2LEN(a0)
  3585.     move.w    d0,AUD3LEN(a0)
  3586.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,DMACON(a0)
  3587.     rts
  3588.  
  3589. *******************************************************************************
  3590.  
  3591. SoftInt_14CbitM:
  3592.     CONVERT_PRE
  3593.  
  3594.     move.l    d2,a0                ;get buffer ptr
  3595.     move.l    d5,a5                ;get buffer ptr
  3596.     move.l    p_CalibrationTable(a6),a3
  3597.     moveq    #0,d3
  3598. .loop
  3599.  
  3600.  IFGE    __CPU-68020
  3601.     move.w    (a1)+,d3
  3602.     move.w    (a3,d3.l*2),d3
  3603.  ELSE
  3604.     moveq    #0,d3
  3605.     move.w    (a1)+,d3
  3606.      add.w    d3,d3
  3607.      move.w    (a3,d3.l),d3
  3608.  ENDC
  3609.     move.b    d3,d1
  3610.     lsl.l    #8,d1                ;xxxxAAxx
  3611.     move.w    d3,d2
  3612.     lsl.l    #8,d2                ;xxaaxxxx
  3613.  IFGE    __CPU-68020
  3614.     move.w    (a1)+,d3
  3615.     move.w    (a3,d3.l*2),d3
  3616.  ELSE
  3617.     moveq    #0,d3
  3618.     move.w    (a1)+,d3
  3619.      add.w    d3,d3
  3620.      move.w    (a3,d3.l),d3
  3621.  ENDC
  3622.     move.b    d3,d1
  3623.     lsl.l    #8,d1                ;xxAABBxx
  3624.     move.w    d3,d2
  3625.     lsl.l    #8,d2                ;aabbxxxx
  3626.  IFGE    __CPU-68020
  3627.     move.w    (a1)+,d3
  3628.     move.w    (a3,d3.l*2),d3
  3629.  ELSE
  3630.     moveq    #0,d3
  3631.     move.w    (a1)+,d3
  3632.      add.w    d3,d3
  3633.      move.w    (a3,d3.l),d3
  3634.  ENDC
  3635.     move.b    d3,d1
  3636.     lsl.l    #8,d1                ;AABBCCxx
  3637.     move.w    d3,d2                ;aabbccxx
  3638.  
  3639.  IFGE    __CPU-68020
  3640.     move.w    (a1)+,d3
  3641.     move.w    (a3,d3.l*2),d3
  3642.  ELSE
  3643.     moveq    #0,d3
  3644.     move.w    (a1)+,d3
  3645.      add.w    d3,d3
  3646.      move.w    (a3,d3.l),d3
  3647.  ENDC
  3648.     move.b    d3,d1                ;AABBCCDD
  3649.     lsr.w    #8,d3
  3650.     move.b    d3,d2                ;aabbccdd
  3651.  
  3652.     move.l    d1,(a5)+
  3653.     move.l    d2,(a0)+
  3654.  
  3655.     dbf    d0,.loop
  3656.     move.l    a0,d2                ;save buffer ptr
  3657.     move.l    a5,d5                ;save buffer ptr
  3658.  
  3659.     CONVERT_POST
  3660.  
  3661.     lsr.l    #1,d0
  3662.     move.w    d0,AUD0LEN(a0)
  3663.     move.w    d0,AUD1LEN(a0)
  3664.     move.w    d0,AUD2LEN(a0)
  3665.     move.w    d0,AUD3LEN(a0)
  3666.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,DMACON(a0)
  3667.     rts
  3668.  
  3669. *******************************************************************************
  3670.  
  3671. SoftInt_14CbitMH:
  3672.     CONVERT_PRE
  3673.  
  3674.     move.l    d2,a0                ;get buffer ptr
  3675.     move.l    d5,a5                ;get buffer ptr
  3676.     move.l    p_CalibrationTable(a6),a3
  3677.     moveq    #0,d3
  3678. .loop
  3679.  
  3680.  IFGE    __CPU-68020
  3681.     move.w    (a1),d3
  3682.     move.w    (a3,d3.l*2),d3
  3683.  ELSE
  3684.     moveq    #0,d3
  3685.     move.w    (a1),d3
  3686.      add.w    d3,d3
  3687.      move.w    (a3,d3.l),d3
  3688.  ENDC
  3689.     move.b    d3,d1
  3690.     lsl.l    #8,d1                ;xxxxAAxx
  3691.     move.w    d3,d2
  3692.     lsl.l    #8,d2                ;xxaaxxxx
  3693.  IFGE    __CPU-68020
  3694.     move.w    4(a1),d3
  3695.     move.w    (a3,d3.l*2),d3
  3696.  ELSE
  3697.     moveq    #0,d3
  3698.     move.w    4(a1),d3
  3699.      add.w    d3,d3
  3700.      move.w    (a3,d3.l),d3
  3701.  ENDC
  3702.     move.b    d3,d1
  3703.     lsl.l    #8,d1                ;xxAABBxx
  3704.     move.w    d3,d2
  3705.     lsl.l    #8,d2                ;aabbxxxx
  3706.  IFGE    __CPU-68020
  3707.     move.w    8(a1),d3
  3708.     move.w    (a3,d3.l*2),d3
  3709.  ELSE
  3710.     moveq    #0,d3
  3711.     move.w    8(a1),d3
  3712.      add.w    d3,d3
  3713.      move.w    (a3,d3.l),d3
  3714.  ENDC
  3715.     move.b    d3,d1
  3716.     lsl.l    #8,d1                ;AABBCCxx
  3717.     move.w    d3,d2                ;aabbccxx
  3718.  
  3719.  IFGE    __CPU-68020
  3720.     move.w    12(a1),d3
  3721.     move.w    (a3,d3.l*2),d3
  3722.  ELSE
  3723.     moveq    #0,d3
  3724.     move.w    12(a1),d3
  3725.      add.w    d3,d3
  3726.      move.w    (a3,d3.l),d3
  3727.  ENDC
  3728.     move.b    d3,d1                ;AABBCCDD
  3729.     lsr.w    #8,d3
  3730.     move.b    d3,d2                ;aabbccdd
  3731.  
  3732.     move.l    d1,(a5)+
  3733.     add.w    #16,a1
  3734.     move.l    d2,(a0)+
  3735.  
  3736.     dbf    d0,.loop
  3737.     move.l    a0,d2                ;save buffer ptr
  3738.     move.l    a5,d5                ;save buffer ptr
  3739.  
  3740.     CONVERT_POST
  3741.  
  3742.     lsr.l    #1,d0
  3743.     move.w    d0,AUD0LEN(a0)
  3744.     move.w    d0,AUD1LEN(a0)
  3745.     move.w    d0,AUD2LEN(a0)
  3746.     move.w    d0,AUD3LEN(a0)
  3747.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,DMACON(a0)
  3748.     rts
  3749.  
  3750.  
  3751. *******************************************************************************
  3752.  
  3753. SoftInt_14bitS:
  3754.     CONVERT_PRE
  3755.  
  3756.     move.l    d2,a0                ;get buffer ptr
  3757.     move.l    d3,a3                ;get buffer ptr
  3758.     move.l    d4,a4                ;get buffer ptr
  3759.     move.l    d5,a5                ;get buffer ptr
  3760. .loop
  3761.  
  3762. ; Left High
  3763.     move.b    (a1),d1
  3764.     lsl.l    #8,d1
  3765.     move.b    4(a1),d1
  3766.     lsl.l    #8,d1
  3767.     move.b    8(a1),d1
  3768.     lsl.l    #8,d1
  3769.     move.b    12(a1),d1
  3770.     move.l    d1,(a3)+
  3771.  
  3772. ; Left Low
  3773.     move.b    1(a1),d1
  3774.     lsr.b    #2,d1
  3775.     lsl.l    #8,d1
  3776.     move.b    5(a1),d1
  3777.     lsr.b    #2,d1
  3778.     lsl.l    #8,d1
  3779.     move.b    9(a1),d1
  3780.     lsr.b    #2,d1
  3781.     lsl.l    #8,d1
  3782.     move.b    13(a1),d1
  3783.     lsr.b    #2,d1
  3784.     move.l    d1,(a4)+
  3785.  
  3786. ; Right High
  3787.     move.b    2(a1),d1
  3788.     lsl.l    #8,d1
  3789.     move.b    6(a1),d1
  3790.     lsl.l    #8,d1
  3791.     move.b    10(a1),d1
  3792.     lsl.l    #8,d1
  3793.     move.b    14(a1),d1
  3794.     move.l    d1,(a0)+
  3795.  
  3796. ; Right Low
  3797.     move.b    3(a1),d1
  3798.     lsr.b    #2,d1
  3799.     lsl.l    #8,d1
  3800.     move.b    7(a1),d1
  3801.     lsr.b    #2,d1
  3802.     lsl.l    #8,d1
  3803.     move.b    11(a1),d1
  3804.     lsr.b    #2,d1
  3805.     lsl.l    #8,d1
  3806.     move.b    15(a1),d1
  3807.     lsr.b    #2,d1
  3808.     move.l    d1,(a5)+
  3809.  
  3810.     add.w    #16,a1
  3811.     dbf    d0,.loop
  3812.     move.l    a0,d2                ;save buffer ptr
  3813.     move.l    a3,d3                ;save buffer ptr
  3814.     move.l    a4,d4                ;save buffer ptr
  3815.     move.l    a5,d5                ;save buffer ptr
  3816.  
  3817.     CONVERT_POST
  3818.  
  3819.     lsr.l    #1,d0
  3820.     move.w    d0,AUD0LEN(a0)
  3821.     move.w    d0,AUD1LEN(a0)
  3822.     move.w    d0,AUD2LEN(a0)
  3823.     move.w    d0,AUD3LEN(a0)
  3824.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,DMACON(a0)
  3825.     rts
  3826.  
  3827. *******************************************************************************
  3828.  
  3829. SoftInt_14bitSH:
  3830.     CONVERT_PRE
  3831.  
  3832.     move.l    d2,a0                ;get buffer ptr
  3833.     move.l    d3,a3                ;get buffer ptr
  3834.     move.l    d4,a4                ;get buffer ptr
  3835.     move.l    d5,a5                ;get buffer ptr
  3836. .loop
  3837.  
  3838. ; Left High
  3839.     move.b    (a1),d1
  3840.     lsl.l    #8,d1
  3841.     move.b    8(a1),d1
  3842.     lsl.l    #8,d1
  3843.     move.b    16(a1),d1
  3844.     lsl.l    #8,d1
  3845.     move.b    24(a1),d1
  3846.     move.l    d1,(a3)+
  3847.  
  3848. ; Left Low
  3849.     move.b    1(a1),d1
  3850.     lsr.b    #2,d1
  3851.     lsl.l    #8,d1
  3852.     move.b    9(a1),d1
  3853.     lsr.b    #2,d1
  3854.     lsl.l    #8,d1
  3855.     move.b    17(a1),d1
  3856.     lsr.b    #2,d1
  3857.     lsl.l    #8,d1
  3858.     move.b    25(a1),d1
  3859.     lsr.b    #2,d1
  3860.     move.l    d1,(a4)+
  3861.  
  3862. ; Right High
  3863.     move.b    4(a1),d1
  3864.     lsl.l    #8,d1
  3865.     move.b    12(a1),d1
  3866.     lsl.l    #8,d1
  3867.     move.b    20(a1),d1
  3868.     lsl.l    #8,d1
  3869.     move.b    28(a1),d1
  3870.     move.l    d1,(a0)+
  3871.  
  3872. ; Right Low
  3873.     move.b    5(a1),d1
  3874.     lsr.b    #2,d1
  3875.     lsl.l    #8,d1
  3876.     move.b    13(a1),d1
  3877.     lsr.b    #2,d1
  3878.     lsl.l    #8,d1
  3879.     move.b    21(a1),d1
  3880.     lsr.b    #2,d1
  3881.     lsl.l    #8,d1
  3882.     move.b    29(a1),d1
  3883.     lsr.b    #2,d1
  3884.     move.l    d1,(a5)+
  3885.  
  3886.     add.w    #32,a1
  3887.     dbf    d0,.loop
  3888.     move.l    a0,d2                ;save buffer ptr
  3889.     move.l    a3,d3                ;save buffer ptr
  3890.     move.l    a4,d4                ;save buffer ptr
  3891.     move.l    a5,d5                ;save buffer ptr
  3892.  
  3893.     CONVERT_POST
  3894.  
  3895.     lsr.l    #1,d0
  3896.     move.w    d0,AUD0LEN(a0)
  3897.     move.w    d0,AUD1LEN(a0)
  3898.     move.w    d0,AUD2LEN(a0)
  3899.     move.w    d0,AUD3LEN(a0)
  3900.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,DMACON(a0)
  3901.     rts
  3902.  
  3903.  
  3904. *******************************************************************************
  3905.  
  3906. SoftInt_14CbitS:
  3907.     CONVERT_PRE
  3908.  
  3909.     move.l    d2,a0                ;get buffer ptr
  3910.     move.l    d3,a3                ;get buffer ptr
  3911.     move.l    d4,a4                ;get buffer ptr
  3912.     move.l    d5,a5                ;get buffer ptr
  3913.     push    a6
  3914.     move.l    p_CalibrationTable(a6),a6
  3915.     moveq    #0,d3
  3916. .loop
  3917.  
  3918. ; Left
  3919.  IFGE    __CPU-68020
  3920.     move.w    (a1),d3
  3921.     move.w    (a6,d3.l*2),d3
  3922.  ELSE
  3923.     moveq    #0,d3
  3924.     move.w    (a1),d3
  3925.      add.w    d3,d3
  3926.      move.w    (a6,d3.l),d3
  3927.  ENDC
  3928.     move.b    d3,d1
  3929.     lsl.l    #8,d1                ;xxxxAAxx
  3930.     move.w    d3,d2
  3931.     lsl.l    #8,d2                ;xxaaxxxx
  3932.  IFGE    __CPU-68020
  3933.     move.w    4(a1),d3
  3934.     move.w    (a6,d3.l*2),d3
  3935.  ELSE
  3936.     moveq    #0,d3
  3937.     move.w    4(a1),d3
  3938.      add.w    d3,d3
  3939.      move.w    (a6,d3.l),d3
  3940.  ENDC
  3941.     move.b    d3,d1
  3942.     lsl.l    #8,d1                ;xxAABBxx
  3943.     move.w    d3,d2
  3944.     lsl.l    #8,d2                ;aabbxxxx
  3945.  IFGE    __CPU-68020
  3946.     move.w    8(a1),d3
  3947.     move.w    (a6,d3.l*2),d3
  3948.  ELSE
  3949.     moveq    #0,d3
  3950.     move.w    8(a1),d3
  3951.      add.w    d3,d3
  3952.      move.w    (a6,d3.l),d3
  3953.  ENDC
  3954.     move.b    d3,d1
  3955.     lsl.l    #8,d1                ;AABBCCxx
  3956.     move.w    d3,d2                ;aabbccxx
  3957.  
  3958.  IFGE    __CPU-68020
  3959.     move.w    12(a1),d3
  3960.     move.w    (a6,d3.l*2),d3
  3961.  ELSE
  3962.     moveq    #0,d3
  3963.     move.w    12(a1),d3
  3964.      add.w    d3,d3
  3965.      move.w    (a6,d3.l),d3
  3966.  ENDC
  3967.     move.b    d3,d1                ;AABBCCDD
  3968.     lsr.w    #8,d3
  3969.     move.b    d3,d2                ;aabbccdd
  3970.  
  3971.     move.l    d1,(a4)+
  3972.     move.l    d2,(a3)+
  3973.  
  3974. ; Right
  3975.  IFGE    __CPU-68020
  3976.     move.w    2(a1),d3
  3977.     move.w    (a6,d3.l*2),d3
  3978.  ELSE
  3979.     moveq    #0,d3
  3980.     move.w    2(a1),d3
  3981.      add.w    d3,d3
  3982.      move.w    (a6,d3.l),d3
  3983.  ENDC
  3984.     move.b    d3,d1
  3985.     lsl.l    #8,d1                ;xxxxAAxx
  3986.     move.w    d3,d2
  3987.     lsl.l    #8,d2                ;xxaaxxxx
  3988.  IFGE    __CPU-68020
  3989.     move.w    6(a1),d3
  3990.     move.w    (a6,d3.l*2),d3
  3991.  ELSE
  3992.     moveq    #0,d3
  3993.     move.w    6(a1),d3
  3994.      add.w    d3,d3
  3995.      move.w    (a6,d3.l),d3
  3996.  ENDC
  3997.     move.b    d3,d1
  3998.     lsl.l    #8,d1                ;xxAABBxx
  3999.     move.w    d3,d2
  4000.     lsl.l    #8,d2                ;aabbxxxx
  4001.  IFGE    __CPU-68020
  4002.     move.w    10(a1),d3
  4003.     move.w    (a6,d3.l*2),d3
  4004.  ELSE
  4005.     moveq    #0,d3
  4006.     move.w    10(a1),d3
  4007.      add.w    d3,d3
  4008.      move.w    (a6,d3.l),d3
  4009.  ENDC
  4010.     move.b    d3,d1
  4011.     lsl.l    #8,d1                ;AABBCCxx
  4012.     move.w    d3,d2                ;aabbccxx
  4013.  
  4014.  IFGE    __CPU-68020
  4015.     move.w    14(a1),d3
  4016.     move.w    (a6,d3.l*2),d3
  4017.  ELSE
  4018.     moveq    #0,d3
  4019.     move.w    14(a1),d3
  4020.      add.w    d3,d3
  4021.      move.w    (a6,d3.l),d3
  4022.  ENDC
  4023.     move.b    d3,d1                ;AABBCCDD
  4024.     lsr.w    #8,d3
  4025.     move.b    d3,d2                ;aabbccdd
  4026.  
  4027.     move.l    d1,(a5)+
  4028.     add.w    #16,a1
  4029.     move.l    d2,(a0)+
  4030.  
  4031.     dbf    d0,.loop
  4032.     pop    a6
  4033.     move.l    a0,d2                ;save buffer ptr
  4034.     move.l    a3,d3                ;save buffer ptr
  4035.     move.l    a4,d4                ;save buffer ptr
  4036.     move.l    a5,d5                ;save buffer ptr
  4037.  
  4038.     CONVERT_POST
  4039.  
  4040.     lsr.l    #1,d0
  4041.     move.w    d0,AUD0LEN(a0)
  4042.     move.w    d0,AUD1LEN(a0)
  4043.     move.w    d0,AUD2LEN(a0)
  4044.     move.w    d0,AUD3LEN(a0)
  4045.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,DMACON(a0)
  4046.     rts
  4047.  
  4048.  
  4049. *******************************************************************************
  4050.  
  4051. SoftInt_14CbitSH:
  4052.     CONVERT_PRE
  4053.  
  4054.     move.l    d2,a0                ;get buffer ptr
  4055.     move.l    d3,a3                ;get buffer ptr
  4056.     move.l    d4,a4                ;get buffer ptr
  4057.     move.l    d5,a5                ;get buffer ptr
  4058.     push    a6
  4059.     move.l    p_CalibrationTable(a6),a6
  4060.     moveq    #0,d3
  4061. .loop
  4062.  
  4063. ; Left
  4064.  IFGE    __CPU-68020
  4065.     move.w    (a1),d3
  4066.     move.w    (a6,d3.l*2),d3
  4067.  ELSE
  4068.     moveq    #0,d3
  4069.     move.w    (a1),d3
  4070.      add.w    d3,d3
  4071.      move.w    (a6,d3.l),d3
  4072.  ENDC
  4073.     move.b    d3,d1
  4074.     lsl.l    #8,d1                ;xxxxAAxx
  4075.     move.w    d3,d2
  4076.     lsl.l    #8,d2                ;xxaaxxxx
  4077.  IFGE    __CPU-68020
  4078.     move.w    8(a1),d3
  4079.     move.w    (a6,d3.l*2),d3
  4080.  ELSE
  4081.     moveq    #0,d3
  4082.     move.w    8(a1),d3
  4083.      add.w    d3,d3
  4084.      move.w    (a6,d3.l),d3
  4085.  ENDC
  4086.     move.b    d3,d1
  4087.     lsl.l    #8,d1                ;xxAABBxx
  4088.     move.w    d3,d2
  4089.     lsl.l    #8,d2                ;aabbxxxx
  4090.  IFGE    __CPU-68020
  4091.     move.w    16(a1),d3
  4092.     move.w    (a6,d3.l*2),d3
  4093.  ELSE
  4094.     moveq    #0,d3
  4095.     move.w    16(a1),d3
  4096.      add.w    d3,d3
  4097.      move.w    (a6,d3.l),d3
  4098.  ENDC
  4099.     move.b    d3,d1
  4100.     lsl.l    #8,d1                ;AABBCCxx
  4101.     move.w    d3,d2                ;aabbccxx
  4102.  
  4103.  IFGE    __CPU-68020
  4104.     move.w    24(a1),d3
  4105.     move.w    (a6,d3.l*2),d3
  4106.  ELSE
  4107.     moveq    #0,d3
  4108.     move.w    24(a1),d3
  4109.      add.w    d3,d3
  4110.      move.w    (a6,d3.l),d3
  4111.  ENDC
  4112.     move.b    d3,d1                ;AABBCCDD
  4113.     lsr.w    #8,d3
  4114.     move.b    d3,d2                ;aabbccdd
  4115.  
  4116.     move.l    d1,(a4)+
  4117.     move.l    d2,(a3)+
  4118.  
  4119. ; Right
  4120.  IFGE    __CPU-68020
  4121.     move.w    4(a1),d3
  4122.     move.w    (a6,d3.l*2),d3
  4123.  ELSE
  4124.     moveq    #0,d3
  4125.     move.w    4(a1),d3
  4126.      add.w    d3,d3
  4127.      move.w    (a6,d3.l),d3
  4128.  ENDC
  4129.     move.b    d3,d1
  4130.     lsl.l    #8,d1                ;xxxxAAxx
  4131.     move.w    d3,d2
  4132.     lsl.l    #8,d2                ;xxaaxxxx
  4133.  IFGE    __CPU-68020
  4134.     move.w    12(a1),d3
  4135.     move.w    (a6,d3.l*2),d3
  4136.  ELSE
  4137.     moveq    #0,d3
  4138.     move.w    12(a1),d3
  4139.      add.w    d3,d3
  4140.      move.w    (a6,d3.l),d3
  4141.  ENDC
  4142.     move.b    d3,d1
  4143.     lsl.l    #8,d1                ;xxAABBxx
  4144.     move.w    d3,d2
  4145.     lsl.l    #8,d2                ;aabbxxxx
  4146.  IFGE    __CPU-68020
  4147.     move.w    20(a1),d3
  4148.     move.w    (a6,d3.l*2),d3
  4149.  ELSE
  4150.     moveq    #0,d3
  4151.     move.w    20(a1),d3
  4152.      add.w    d3,d3
  4153.      move.w    (a6,d3.l),d3
  4154.  ENDC
  4155.     move.b    d3,d1
  4156.     lsl.l    #8,d1                ;AABBCCxx
  4157.     move.w    d3,d2                ;aabbccxx
  4158.  
  4159.  IFGE    __CPU-68020
  4160.     move.w    28(a1),d3
  4161.     move.w    (a6,d3.l*2),d3
  4162.  ELSE
  4163.     moveq    #0,d3
  4164.     move.w    28(a1),d3
  4165.      add.w    d3,d3
  4166.      move.w    (a6,d3.l),d3
  4167.  ENDC
  4168.     move.b    d3,d1                ;AABBCCDD
  4169.     lsr.w    #8,d3
  4170.     move.b    d3,d2                ;aabbccdd
  4171.  
  4172.     move.l    d1,(a5)+
  4173.     add.w    #32,a1
  4174.     move.l    d2,(a0)+
  4175.  
  4176.     dbf    d0,.loop
  4177.     pop    a6
  4178.     move.l    a0,d2                ;save buffer ptr
  4179.     move.l    a3,d3                ;save buffer ptr
  4180.     move.l    a4,d4                ;save buffer ptr
  4181.     move.l    a5,d5                ;save buffer ptr
  4182.  
  4183.     CONVERT_POST
  4184.  
  4185.     lsr.l    #1,d0
  4186.     move.w    d0,AUD0LEN(a0)
  4187.     move.w    d0,AUD1LEN(a0)
  4188.     move.w    d0,AUD2LEN(a0)
  4189.     move.w    d0,AUD3LEN(a0)
  4190.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,DMACON(a0)
  4191.     rts
  4192.  
  4193.  
  4194.  
  4195.  
  4196.  
  4197.  
  4198.  
  4199. *******************************************************************************
  4200. ***** DMA playback routines ***************************************************
  4201. *******************************************************************************
  4202.  
  4203. ;in:
  4204. * a2    AudioCtrl
  4205. * a3    paula
  4206. * a4    custom
  4207. * a5    paulaBase
  4208. * a6    ExecBase
  4209. ; out:
  4210. * d0    AHIsub_Start return code
  4211.  
  4212. DMA_Start:
  4213.     PRINTF    2,"DMA_Start()"
  4214.  
  4215. * Allocate DMA buffers
  4216.     move.l    #DMABUFFSAMPLES*8,d0            ; 4 channels, double buffers
  4217.     move.l    #MEMF_CHIP|MEMF_PUBLIC|MEMF_CLEAR,d1
  4218.     call    AllocVec
  4219.     move.l    d0,p_DMAbuffer(a3)
  4220.     beq    .nomem
  4221.  
  4222.     move.l    #DMABUFFSAMPLES,d1
  4223.     move.l    d0,p_AudPtr1A(a3)
  4224.     add.l    d1,d0
  4225.     move.l    d0,p_AudPtr1B(a3)
  4226.     add.l    d1,d0
  4227.     move.l    d0,p_AudPtr2A(a3)
  4228.     add.l    d1,d0
  4229.     move.l    d0,p_AudPtr2B(a3)
  4230.     add.l    d1,d0
  4231.     move.l    d0,p_AudPtr3A(a3)
  4232.     add.l    d1,d0
  4233.     move.l    d0,p_AudPtr3B(a3)
  4234.     add.l    d1,d0
  4235.     move.l    d0,p_AudPtr4A(a3)
  4236.     add.l    d1,d0
  4237.     move.l    d0,p_AudPtr4B(a3)
  4238.  
  4239. * Set up audio hardware interrupts
  4240.     move.l    #AudioInterruptDMA,IS_CODE+p_PlayInt(a3)
  4241.     move.l    a3,IS_DATA+p_PlayInt(a3)
  4242.  
  4243.     lea    p_PlayInt(a3),a1
  4244.     moveq    #INTB_AUD0,d0
  4245.     call    SetIntVector
  4246.     lea    p_PlayInt(a3),a1
  4247.     moveq    #INTB_AUD1,d0
  4248.     call    SetIntVector
  4249.     lea    p_PlayInt(a3),a1
  4250.     moveq    #INTB_AUD2,d0
  4251.     call    SetIntVector
  4252.     lea    p_PlayInt(a3),a1
  4253.     moveq    #INTB_AUD3,d0
  4254.     call    SetIntVector
  4255.  
  4256.     clr.w    p_DisableCount(a3)
  4257.  
  4258. * Use timer.device to clock the PlayerFunc() using a software interrupt/msg port
  4259.  
  4260.     lea    p_TimerPort+MP_MSGLIST(a3),a0
  4261.     NEWLIST    a0
  4262.  
  4263.     lea    p_TimerPort(a3),a0
  4264.     move.b    #NT_MSGPORT,LN_TYPE(a0)
  4265.     move.b    #PA_SOFTINT,MP_FLAGS(a0)
  4266.     lea    p_TimerInt(a3),a1
  4267.     move.l    a1,MP_SIGTASK(a0)
  4268.     
  4269.     move.b    #32,p_TimerInt+LN_PRI(a3)    ; Highest priority to keep it steady
  4270.     lea    PlayerFunc(pc),a0
  4271.     move.l    a0,p_TimerInt+IS_CODE(a3)
  4272.     move.l    a3,p_TimerInt+IS_DATA(a3)
  4273.  
  4274.     lea    p_TimerPort(a3),a0
  4275.     moveq    #IOTV_SIZE,d0
  4276.     call    CreateIORequest
  4277.     move.l    d0,p_TimerReq(a3)
  4278.     beq    .notimer
  4279.  
  4280.     lea    timerName(pc),a0
  4281.     moveq    #UNIT_ECLOCK,d0
  4282.     move.l    p_TimerReq(a3),a1
  4283.     moveq    #0,d0
  4284.     call    OpenDevice
  4285.     move.b    d0,p_TimerDev(a3)
  4286.     bne    .notimer
  4287.  
  4288.     move.l    p_TimerReq(a3),a0
  4289.     move.l    IO_DEVICE(a0),pb_TimerLib(a5)
  4290.  
  4291.     move.l    a5,a6
  4292.     bsr    DMA_Update                ;Calc p_EClock/p_EPeriod
  4293.                             ;and p_EAlarm
  4294.     ; Add p_EPeriod to the alarm time
  4295.     move.l    p_EAlarm+EV_LO(a3),d0
  4296.     move.l    p_EAlarm+EV_HI(a3),d1
  4297.     move.l    p_EPeriod(a3),d2
  4298.     moveq    #0,d3
  4299.     add.l    d0,d2
  4300.     addx.l    d1,d3
  4301.     move.l    d2,p_EAlarm+EV_LO(a3)
  4302.     move.l    d3,p_EAlarm+EV_HI(a3)
  4303.  
  4304.     clr.w    p_TimerCommFlag(a3)
  4305.  
  4306.     move.l    p_TimerReq(a3),a1
  4307.     move.w    #TR_ADDREQUEST,IO_COMMAND(a1)
  4308.     move.l    p_EPeriod(a3),IOTV_TIME+EV_LO(a1)
  4309.     clr.l    IOTV_TIME+EV_HI(a1)
  4310.     bsr    BeginIO
  4311.  
  4312.     or.w    #INTF_SETCLR|INTF_AUDIO,p_IRQMask(a3)
  4313.     move.w    #INTF_SETCLR|INTF_AUDIO,INTENA(a4)    ;enable all
  4314.     move.w    #INTF_SETCLR|INTF_AUDIO,INTREQ(a4)    ;start all
  4315.  
  4316.     moveq    #AHIE_OK,d0
  4317. .exit
  4318.     rts
  4319.  
  4320. .notimer
  4321.     moveq    #AHIE_UNKNOWN,d0
  4322.     bra    .exit
  4323.  
  4324. .nomem
  4325.     moveq    #AHIE_NOMEM,d0
  4326.     bra    .exit
  4327.  
  4328.  
  4329. ;in:
  4330. * a2    AudioCtrl
  4331. * a3    paula
  4332. * a6    paulaBase
  4333.  
  4334. DMA_Update:
  4335.     PRINTF    2,"DMA_Update()"
  4336.     move.l    pb_TimerLib(a6),d0
  4337.     beq    .error
  4338.     push    a6
  4339.     move.l    d0,a6
  4340.     lea    p_EAlarm(a3),a0
  4341.     call    ReadEClock
  4342.     move.l    d0,p_EClock(a3)
  4343.     pop    a6
  4344.  
  4345.     lsl.l    #8,d0
  4346.     move.l    ahiac_PlayerFreq(a2),d1
  4347.     lsr.l    #8,d1
  4348.     beq    .error
  4349.  
  4350.  IFGE    __CPU-68020
  4351.     divu.l    d1,d0
  4352.  ELSE
  4353.     move.l    pb_UtilLib(a6),a0
  4354.     jsr    _LVOUDivMod32(a0)
  4355.  ENDIF
  4356.     move.l    d0,p_EPeriod(a3)
  4357. .exit
  4358.     rts
  4359.  
  4360. .error
  4361.     move.l    #709379/50,p_EPeriod(a3)    ;Approx 50 Hz
  4362.     bra    .exit
  4363.     
  4364.  
  4365. ;in:
  4366. * a2    AudioCtrl
  4367. * a3    paula
  4368. * a4    custom
  4369. * a5    paulaBase
  4370. * a6    ExecBase
  4371.  
  4372. DMA_Stop:
  4373.     PRINTF    2,"DMA_Stop()"
  4374.  
  4375.     and.w    #INTF_AUDIO,p_IRQMask(a3)
  4376.     move.w    #INTF_AUDIO,INTENA(a4)
  4377.     move.w    #DMAF_AUDIO,DMACON(a4)        ;Disable DMA
  4378.     move.w    #INTF_AUDIO,INTREQ(a4)        ;Clear any waiting interrupts
  4379.  
  4380.     tst.b    p_TimerDev(a3)
  4381.     bne    .notimer
  4382.  
  4383. * Ask timer softint to stop
  4384.  
  4385.     addq.w    #1,p_TimerCommFlag(a3)
  4386. .waittimer
  4387.     tst.w    p_TimerCommFlag(a3)
  4388.     beq    .closetimer
  4389.     move.l    pb_DosLib(a5),a6
  4390.     moveq    #1,d1
  4391.     call    Delay
  4392.     bra    .waittimer
  4393. .closetimer
  4394.  
  4395.     move.b    #-1,p_TimerDev(a3)
  4396.     clr.l    pb_TimerLib(a5)
  4397.  
  4398.     move.l    pb_SysLib(a5),a6
  4399.     move.l    p_TimerReq(a3),a0
  4400.     call    CloseDevice
  4401. .notimer
  4402.     move.l    p_TimerReq(a3),a0
  4403.     clr.l    p_TimerReq(a3)
  4404.     call    DeleteIORequest
  4405.  
  4406.     move.l    #Interrupt_Dummy,IS_CODE+p_PlayInt(a3)
  4407.  
  4408.     lea    p_PlayInt(a3),a1
  4409.     moveq    #INTB_AUD0,d0
  4410.     call    SetIntVector
  4411.     lea    p_PlayInt(a3),a1
  4412.     moveq    #INTB_AUD1,d0
  4413.     call    SetIntVector
  4414.     lea    p_PlayInt(a3),a1
  4415.     moveq    #INTB_AUD2,d0
  4416.     call    SetIntVector
  4417.     lea    p_PlayInt(a3),a1
  4418.     moveq    #INTB_AUD3,d0
  4419.     call    SetIntVector
  4420.  
  4421.     move.l    p_DMAbuffer(a3),a1
  4422.     clr.l    p_DMAbuffer(a3)
  4423.     call    FreeVec
  4424.  
  4425.     rts
  4426.  
  4427.  
  4428. ****** [driver].audio/AHIsub_#? *********************************************
  4429. *
  4430. *   NAME
  4431. *       AHIsub_SetEffect -- Set effect.
  4432. *       AHIsub_SetFreq -- Set frequency.
  4433. *       AHIsub_SetSound -- Set sound.
  4434. *       AHIsub_SetVol -- Set volume and stereo panning.
  4435. *       AHIsub_LoadSound -- Prepare a sound for playback.
  4436. *       AHIsub_UnloadSound -- Discard a sound.
  4437. *
  4438. *   SYNOPSIS
  4439. *       See functions in 'ahi.device'.
  4440. *
  4441. *   IMPLEMENTATION
  4442. *       If AHIsub_AllocAudio() did not return with bit AHISB_MIXING set,
  4443. *       all user calls to these function will be routed to the driver.
  4444. *
  4445. *       If AHIsub_AllocAudio() did return with bit AHISB_MIXING set, the
  4446. *       calls will first be routed to the driver, and only handled by
  4447. *       'ahi.device' if the driver returned AHIS_UNKNOWN. This way it is
  4448. *       possible to add effects that the sound card handles on its own, like
  4449. *       filter and echo effects.
  4450. *
  4451. *       For what each function does, see the autodocs for 'ahi.device'.
  4452. *
  4453. *   INPUTS
  4454. *       See functions in 'ahi.device'.
  4455. *
  4456. *   NOTES
  4457. *       See functions in 'ahi.device'.
  4458. *
  4459. *   SEE ALSO
  4460. *       ahi.device/AHI_SetEffect(), ahi.device/AHI_SetFreq(),
  4461. *       ahi.device/AHI_SetSound(), ahi.device/AHI_SetVol(),
  4462. *       ahi.device/AHI_LoadSound(), ahi.device/AHI_UnloadSound()
  4463. *       
  4464. *
  4465. *****************************************************************************
  4466. *
  4467. *
  4468.  
  4469.  
  4470. *****************************************************************************
  4471. * Panning is ignored, and negative volume is not supported.
  4472.  
  4473. AHIsub_SetVol:
  4474.     push    a3
  4475.     move.l    ahiac_DriverData(a2),a3
  4476.     btst.b    #PB_DMA,p_Flags(a3)
  4477.     beq    AHIsub_NoDMA
  4478.  
  4479.     PRINTF    2,"AHIsub_SetVol()"
  4480.     mulu.w    #channel_SIZEOF,d0
  4481.     lea    p_Channels(a3),a0
  4482.     add.l    d0,a0
  4483.     asr.l    #8,d1
  4484.     asr.w    #2,d1
  4485.     bpl    .plus
  4486.     neg.w    d1
  4487. .plus
  4488.     bsr    AHIsub_Disable
  4489.  
  4490. * Store volume and scale according to the master volume
  4491.     move.w    d1,ch_NextVolumeNorm(a0)
  4492.     move.l    p_MasterVolume(a3),d0
  4493.     cmp.l    #$10000,d0
  4494.     blo    .scale1
  4495.     move.w    d1,d0
  4496.     bra    .store1
  4497. .scale1
  4498.     mulu.w    d1,d0
  4499.     swap.w    d0
  4500. .store1
  4501.     move.w    d0,ch_NextVolume(a0)
  4502.  
  4503.     btst    #AHISB_IMM,d3
  4504.     beq    .noimm
  4505.     move.w    d1,ch_VolumeNorm(a0)
  4506.     move.l    p_MasterVolume(a3),d0
  4507.     cmp.l    #$10000,d0
  4508.     blo    .scale2
  4509.     move.w    d1,d0
  4510.     bra    .store2
  4511. .scale2
  4512.     mulu.w    d1,d0
  4513.     swap.w    d0
  4514. .store2
  4515.     move.w    d0,ch_Volume(a0)
  4516. ;    move.l    ch_PerVol(a0),ch_AudPerVol(a0)
  4517.     move.l    ch_RegBase(a0),a1
  4518.     move.w    d0,AUDVOL(a1)
  4519. .noimm
  4520.  
  4521.     bsr    AHIsub_Enable
  4522.  
  4523.     moveq    #0,d0                ; Return NULL!
  4524.  
  4525.     pop    a3
  4526.     rts
  4527.  
  4528. *****************************************************************************
  4529. * If the frequency is higher than the audio DMA can handle, the samples will
  4530. * be decimated before they are played. The frequency will only take effect
  4531. * immediately if the decimate factor didn't change, or the new frequency
  4532. * was zero. Otherwise, the frequency will change when the current DMA
  4533. * block is finished.
  4534.  
  4535. AHIsub_SetFreq:
  4536.     push    a3
  4537.     move.l    ahiac_DriverData(a2),a3
  4538.     btst.b    #PB_DMA,p_Flags(a3)
  4539.     beq    AHIsub_NoDMA
  4540.  
  4541.     PRINTF    2,"AHIsub_SetFreq()"
  4542.     push    d3
  4543.     mulu.w    #channel_SIZEOF,d0
  4544.     lea    p_Channels(a3),a0
  4545.     add.l    d0,a0
  4546.  
  4547.     cmp.l    #AHI_MIXFREQ,d1
  4548.     bne    .normal_freq
  4549.     move.l    ahiac_MixFreq(a2),d1
  4550. .normal_freq
  4551.  
  4552.     move.l    #28800,d0
  4553.     tst.w    p_ScreenIsDouble(a3)
  4554.     beq    .1
  4555.     move.l    #48000,d0
  4556. .1
  4557.     moveq    #0,d3            ; Decimate/scale (log)
  4558. .loop
  4559.     cmp.l    d0,d1
  4560.     bls    .scaled
  4561.     addq.l    #1,d3
  4562.     lsr.l    #1,d1
  4563.     bra    .loop
  4564. .scaled
  4565.  
  4566.     tst.l    d1
  4567.     bne    .notnull
  4568.     moveq    #0,d0            ;VVVeeerrryyyy ssslllooowww!!!
  4569.     moveq    #0,d3
  4570.     bra    .gotperiod
  4571. .notnull
  4572.  
  4573.     move.l    p_AudioFreq(a3),d0
  4574.  
  4575.  IFGE    __CPU-68020
  4576.     divu.l    d1,d0
  4577.  ELSE
  4578.     move.l    pb_UtilLib(a6),a1
  4579.     jsr    _LVOUDivMod32(a1)
  4580.  ENDIF
  4581.  
  4582. .gotperiod
  4583.  
  4584.     bsr    AHIsub_Disable
  4585.  
  4586.     move.w    d0,ch_NextPeriod(a0)
  4587.     move.w    d3,ch_NextScale(a0)
  4588.  
  4589.     btst    #AHISB_IMM,d2
  4590.     beq    .noimm
  4591.  
  4592. ; We must not change the frequency if the scale has changed! (Unless it's 0)
  4593.     tst.w    d3
  4594.     beq    .change
  4595.     cmp.w    ch_Scale(a0),d3
  4596.     bne    .nochange
  4597. .change
  4598. ;    move.l    ch_PerVol(a0),ch_AudPerVol(a0)
  4599.     move.l    ch_RegBase(a0),a1
  4600.     move.w    d0,AUDPER(a1)
  4601. .nochange
  4602.  
  4603.     ; Force an interrupt if the channel was paused
  4604.     tst.w    ch_Period(a0)
  4605.     bne    .notzero
  4606.     tst.b    ch_NoInt(a0)
  4607.     bne    .noint
  4608.     lea    custom,a1
  4609.     move.w    ch_IntMask(a0),d1
  4610.     or.w    #INTF_SETCLR,d1
  4611.     move.w    d1,INTREQ(a1)
  4612. .noint
  4613. .notzero
  4614.  
  4615.     move.w    d0,ch_Period(a0)
  4616.     move.w    d3,ch_Scale(a0)
  4617.  
  4618. .noimm
  4619.  
  4620.     bsr    AHIsub_Enable
  4621.  
  4622.     moveq    #0,d0                ; Return NULL!
  4623.     pop    d3
  4624.  
  4625.     pop    a3
  4626.     rts
  4627.  
  4628. *****************************************************************************
  4629.  
  4630. AHIsub_SetSound:
  4631.     push    a3
  4632.     move.l    ahiac_DriverData(a2),a3
  4633.     btst.b    #PB_DMA,p_Flags(a3)
  4634.     beq    AHIsub_NoDMA
  4635.  
  4636.     PRINTF    2,"AHIsub_SetSound()"
  4637.     pushm    d2-d5
  4638.  
  4639.     mulu.w    #channel_SIZEOF,d0
  4640.     lea    p_Channels(a3),a0
  4641.     add.l    d0,a0
  4642.  
  4643.     cmp.w    #AHI_NOSOUND,d1
  4644.     bne    .sound_ok
  4645.     moveq    #0,d2
  4646.     moveq    #0,d3
  4647.     moveq    #AHIST_NOTYPE,d5
  4648.     bra    .update_channel
  4649. .sound_ok
  4650.  
  4651.     mulu.w    #sound_SIZEOF,d1
  4652.     move.l    p_Sounds(a3),a1
  4653.     add.l    d1,a1
  4654.  
  4655.     tst.l    d3
  4656.     bne    .length_ok
  4657.     move.l    so_Length(a1),d3
  4658. .length_ok
  4659.     move.l    so_Type(a1),d5
  4660.  
  4661. .update_channel
  4662.  
  4663.     tst.l    d3
  4664.     bpl    .positive_length
  4665.     neg.l    d3                ; Make positive
  4666.     or.l    #AHIST_BW,d5            ; Mark type as backward-playing
  4667. .positive_length
  4668.  
  4669. ;    PRINTF    0,"New sample! %08lx, %ld, %08lx", d2,d3,d5
  4670.  
  4671.     bsr    AHIsub_Disable
  4672.  
  4673.     move.l    so_Address(a1),ch_NextAddress(a0)
  4674.     move.l    d2,ch_NextOffset(a0)
  4675.     move.l    d3,ch_NextLength(a0)
  4676.     move.l    d5,ch_NextType(a0)
  4677.  
  4678.  
  4679.     btst    #AHISB_IMM,d4
  4680.     beq    .noimm
  4681.  
  4682.     move.l    so_Address(a1),ch_Address(a0)
  4683.     move.l    d2,ch_Offset(a0)
  4684.     move.l    d3,ch_Length(a0)
  4685.     move.l    d5,ch_Type(a0)
  4686.     clr.l    ch_Count(a0)
  4687.     st.b    ch_EndOfSample(a0)        ; Call SoundFunc()
  4688.  
  4689.     lea    custom,a1
  4690.  
  4691. ; Clear pending interrupt (if there was one)
  4692.     st.b    ch_NoInt(a0)
  4693.     move.w    ch_IntMask(a0),INTREQ(a1)
  4694.  
  4695. ; Stop this channel
  4696.     move.w    ch_DMAMask(a0),DMACON(a1)
  4697.  
  4698.     ; Wait for Agnus/Alice to understand
  4699.     push    a6
  4700.     move.l    pb_SysLib(a6),a6
  4701.     call    Disable
  4702.  
  4703.     move.b    VHPOSR(a1),d0
  4704. .vert
  4705.     cmp.b    VHPOSR(a1),d0
  4706.     beq    .vert
  4707. .hori
  4708.     cmp.b    #20,VHPOSR+1(a1)
  4709.     blt    .hori
  4710.  
  4711.     call    Enable
  4712.     pop    a6
  4713.  
  4714. ; When the period reaches 0, Paula will invoke our interrupt routine!
  4715.  
  4716. ; Now just make sure that we receive no more than 1 interrupt.
  4717.     move.l    ch_RegBase(a0),a1
  4718.     move.w    #1,AUDPER(a1)
  4719. .noimm
  4720.  
  4721.     bsr    AHIsub_Enable
  4722.  
  4723.     moveq    #0,d0                ; Return NULL!
  4724.     popm    d2-d5
  4725.  
  4726.     pop    a3
  4727.     rts
  4728.  
  4729. *****************************************************************************
  4730.  
  4731. AHIsub_SetEffect:
  4732.     push    a3
  4733.     move.l    ahiac_DriverData(a2),a3
  4734.     btst.b    #PB_DMA,p_Flags(a3)
  4735.     beq    AHIsub_NoDMA
  4736.  
  4737.     PRINTF    2,"AHIsub_SetEffect()"
  4738.     move.l    ahie_Effect(a0),d0
  4739.     cmp.l    #AHIET_MASTERVOLUME,d0
  4740.     beq    .mastervolume
  4741.     cmp.l    #AHIET_CANCEL|AHIET_MASTERVOLUME,d0
  4742.     beq    .mastervolume_off
  4743.     cmp.l    #AHIET_CHANNELINFO,d0
  4744.     beq    .channelinfo
  4745.     cmp.l    #AHIET_CANCEL|AHIET_CHANNELINFO,d0
  4746.     beq    .channelinfo_off
  4747.  
  4748.     moveq    #AHIE_UNKNOWN,d0        ; Return error code!
  4749. .exit
  4750.     pop    a3
  4751.     rts
  4752.  
  4753. .mastervolume
  4754.     move.l    ahiemv_Volume(a0),d0
  4755. .mastervolume_update
  4756.     move.l    d0,p_MasterVolume(a3)
  4757.  
  4758.     lea    p_Channels(a3),a0
  4759.     moveq    #3,d1
  4760. .mastervolume_loop
  4761.     move.l    p_MasterVolume(a3),d0
  4762.     cmp.l    #$10000,d0
  4763.     blo    .mastervolume_scale1
  4764.     move.w    ch_NextVolumeNorm(a0),d0
  4765.     bra    .mastervolume_store1
  4766. .mastervolume_scale1
  4767.     mulu.w    ch_NextVolumeNorm(a0),d0
  4768.     swap.w    d0
  4769. .mastervolume_store1
  4770.     move.w    d0,ch_NextVolume(a0)
  4771.     move.l    p_MasterVolume(a3),d0
  4772.     cmp.l    #$10000,d0
  4773.     blo    .mastervolume_scale2
  4774.     move.w    ch_VolumeNorm(a0),d0
  4775.     bra    .mastervolume_store2
  4776. .mastervolume_scale2
  4777.     mulu.w    ch_VolumeNorm(a0),d0
  4778.     swap.w    d0
  4779. .mastervolume_store2
  4780.     move.w    d0,ch_Volume(a0)
  4781. ;    move.l    ch_PerVol(a0),ch_AudPerVol(a0)
  4782.     move.l    ch_RegBase(a0),a1
  4783.     move.w    d0,AUDVOL(a1)
  4784.  
  4785.     add.w    #channel_SIZEOF,a0
  4786.     dbf    d1,.mastervolume_loop
  4787.  
  4788.     moveq    #AHIE_OK,d0
  4789.     bra    .exit
  4790.  
  4791. .mastervolume_off
  4792.     move.l    #$10000,d0
  4793.     bra    .mastervolume_update
  4794.  
  4795.  
  4796. .channelinfo
  4797.     move.l    a0,p_ChannelInfo(a3)
  4798.     moveq    #AHIE_OK,d0
  4799.     bra    .exit
  4800.  
  4801. .channelinfo_off
  4802.     clr.l    p_ChannelInfo(a3)
  4803.     moveq    #AHIE_OK,d0
  4804.     bra    .exit
  4805.  
  4806.  
  4807. *****************************************************************************
  4808.  
  4809. AHIsub_LoadSound:
  4810.     push    a3
  4811.     move.l    ahiac_DriverData(a2),a3
  4812.     btst.b    #PB_DMA,p_Flags(a3)
  4813.     beq    AHIsub_NoDMA
  4814.  
  4815.     PRINTF    2,"AHIsub_LoadSound()"
  4816.     cmp.l    #AHIST_SAMPLE,d1
  4817.     beq    .soundok
  4818.     cmp.l    #AHIST_DYNAMICSAMPLE,d1
  4819.     bne    .unknownsound
  4820. .soundok
  4821.     mulu.w    #sound_SIZEOF,d0
  4822.     move.l    p_Sounds(a3),a1
  4823.     add.l    d0,a1
  4824.  
  4825.     move.l    ahisi_Type(a0),d0
  4826.     cmp.l    #AHIST_M8S,d0
  4827.     beq    .sampleok
  4828.     cmp.l    #AHIST_M16S,d0
  4829.     beq    .sampleok
  4830.     cmp.l    #AHIST_S8S,d0
  4831.     beq    .sampleok
  4832.     cmp.l    #AHIST_S16S,d0
  4833.     bne    .unknownsample
  4834. .sampleok
  4835.     move.l    d0,so_Type(a1)
  4836.     move.l    ahisi_Address(a0),so_Address(a1)
  4837.     move.l    ahisi_Length(a0),so_Length(a1)
  4838.  
  4839.     moveq    #AHIE_OK,d0
  4840. .exit
  4841.  
  4842.     pop    a3
  4843.     rts
  4844.  
  4845. .unknownsound
  4846.     moveq    #AHIE_BADSOUNDTYPE,d0
  4847.     bra    .exit
  4848. .unknownsample
  4849.     moveq    #AHIE_BADSAMPLETYPE,d0
  4850.     bra    .exit
  4851.  
  4852. *****************************************************************************
  4853.  
  4854. AHIsub_UnloadSound:
  4855.     push    a3
  4856.     move.l    ahiac_DriverData(a2),a3
  4857.     btst.b    #PB_DMA,p_Flags(a3)
  4858.     beq    AHIsub_NoDMA
  4859.  
  4860.     PRINTF    2,"AHIsub_UnloadSound()"
  4861.     mulu.w    #sound_SIZEOF,d0
  4862.     move.l    p_Sounds(a3),a1
  4863.     add.l    d0,a1
  4864.     move.l    #AHIST_NOTYPE,so_Type(a1)
  4865.     clr.l    so_Address(a1)
  4866.     clr.l    so_Length(a1)
  4867.  
  4868.     moveq    #0,d0                ; Return NULL!
  4869.  
  4870.     pop    a3
  4871.     rts
  4872.  
  4873. *****************************************************************************
  4874.  
  4875. AHIsub_NoDMA:
  4876.     moveq    #AHIS_UNKNOWN,d0        ; Return AHIS_UNKNOWN!
  4877.     pop    a3
  4878.     rts
  4879.  
  4880. *****************************************************************************
  4881.  
  4882. ;in:
  4883. * a1    struct paula *
  4884.  
  4885. PlayerFunc:
  4886.     pushm    std
  4887.  
  4888.     move.l    a1,a3
  4889.     move.l    p_AudioCtrl(a3),a2
  4890.  
  4891.     move.l    4.w,a6
  4892.     lea    p_TimerPort(a3),a0
  4893.     call    GetMsg                ; Remove message
  4894.  
  4895.     tst.w    p_TimerCommFlag(a3)
  4896.     beq    .normal
  4897.  
  4898.     clr.w    p_TimerCommFlag(a3)
  4899.     bra    .exit
  4900.  
  4901. .normal
  4902.     ; Add p_EPeriod to the alarm time
  4903.     move.l    p_EAlarm+EV_LO(a3),d0
  4904.     move.l    p_EAlarm+EV_HI(a3),d1
  4905.     move.l    p_EPeriod(a3),d2
  4906.     moveq    #0,d3
  4907.     add.l    d0,d2
  4908.     addx.l    d1,d3
  4909.     move.l    d2,p_EAlarm+EV_LO(a3)
  4910.     move.l    d3,p_EAlarm+EV_HI(a3)
  4911.  
  4912.     ; Get current time
  4913.     push    a6
  4914.     move.l    p_PaulaBase(a3),a0
  4915.     move.l    pb_TimerLib(a0),a6
  4916.     subq.l    #8,sp
  4917.     move.l    sp,a0
  4918.     call    ReadEClock
  4919.     move.l    EV_LO(sp),d0            ; Current time
  4920.     move.l    EV_HI(sp),d1
  4921.     sub.l    d0,d2                ; Calculate difference (Alarm - Current)
  4922.     subx.l    d1,d3
  4923.     addq.l    #8,sp
  4924.     pop    a6
  4925.  
  4926.     tst.l    d3
  4927.     bpl    .positive
  4928.     moveq    #1,d2
  4929.     moveq    #0,d3                ; Rather small delay...
  4930. .positive
  4931.  
  4932. ;    PRINTF    0,"Delay: %08ld%08ld",d3,d2
  4933.     move.l    p_TimerReq(a3),a1
  4934.     move.w    #TR_ADDREQUEST,IO_COMMAND(a1)
  4935.     move.l    d2,IOTV_TIME+EV_LO(a1)
  4936.     move.l    d3,IOTV_TIME+EV_HI(a1)
  4937.     bsr    BeginIO
  4938.  
  4939.     bsr    AHIsub_Disable
  4940.  
  4941.     ; Handle the ChannelInfo effect
  4942.  
  4943.     move.l    p_ChannelInfo(a3),d0
  4944.     beq    .nochannelinfo
  4945.     move.l    d0,a0
  4946.     lea    ahieci_Offset(a0),a1
  4947.     move.w    ahieci_Channels(a0),d0
  4948.     subq.w    #1,d0
  4949.     bmi    .nochannelinfo
  4950.     lea    p_Channels(a3),a4
  4951. .loop
  4952.     move.l    ch_Offset(a4),(a1)+
  4953.     add.w    #channel_SIZEOF,a4
  4954.     dbf    d0,.loop
  4955.  
  4956.     move.l    p_ChannelInfo(a3),a1
  4957.     move.l    ahieci_Func(a1),d0
  4958.     beq    .nochannelinfo
  4959.     move.l    d0,a0
  4960.     move.l    h_Entry(a0),a4
  4961.     jsr    (a4)
  4962.  
  4963. ;    lea    p_Channels(a3),a4
  4964. ;    PRINTF    0,"CI: %ld, %ld, %ld, %ld",ch_Offset(a4),ch_Offset+channel_SIZEOF(a4),ch_Offset+channel_SIZEOF*2(a4),ch_Offset+channel_SIZEOF*3(a4)
  4965. .nochannelinfo
  4966.  
  4967.     ; Call the PlayerFunc()
  4968.  
  4969.     move.l    ahiac_PlayerFunc(a2),d0
  4970.     move.l    d0,a0
  4971.     beq    .noplayerfunc
  4972.     sub.l    a1,a1                ; IMPORTANT!
  4973.     move.l    h_Entry(a0),a4
  4974.     PRINTF    8,"Calling PlayerFunc(%08lx,%08lx,%08lx)",a0,a2,a1
  4975.     jsr    (a4)
  4976. .noplayerfunc
  4977.  
  4978.     bsr    AHIsub_Enable
  4979.  
  4980. .exit
  4981.     moveq    #0,d0
  4982.     popm    std
  4983.     rts
  4984.  
  4985. *****************************************************************************
  4986.  
  4987. ;in:
  4988. * d0    scratch
  4989. * d1.w    INTENAR & INTREQR
  4990. * a0    custom
  4991. * a1    struct paula *
  4992. * a5    &AudioInterruptDMA
  4993. * a6    ExecBase
  4994.  
  4995. AudioInterruptDMA:
  4996.     pushm    std
  4997.  
  4998.     PRINTF    3,"."
  4999.     PRINTF    6,"AudioInterruptDMA"
  5000.  
  5001.     move.l    p_AudioCtrl(a1),a4
  5002.     lea    p_Channels(a1),a5
  5003.     lea    p_AudPtr1A(a1),a6
  5004.     move.w    d1,d7
  5005.  
  5006.     move.w    ch_IntMask(a5),d0
  5007.     and.w    d7,d0
  5008.     beq    .not0
  5009.  
  5010.     move.l    ch_RegBase(a5),a0
  5011.     move.l    ch_PerVol(a5),AUDPERVOL(a0)
  5012. ;    move.l    ch_AudPerVol(a5),AUDPERVOL(a0)
  5013. ;    move.l    ch_PerVol(a5),ch_AudPerVol(a5)
  5014.  
  5015.     bsr    DMA_HandleInt
  5016.  
  5017.     move.w    ch_IntMask(a5),custom+INTREQ        ; Clear the interrupt
  5018.     move.l    ch_RegBase(a5),a0
  5019.     move.l    (a6),AUDLC(a0)
  5020.     move.w    ch_DMALength(a5),AUDLEN(a0)
  5021.  
  5022.     clr.b    ch_NoInt(a5)
  5023. .not0
  5024.  
  5025.     add.w    #channel_SIZEOF,a5
  5026.     addq.l    #8,a6
  5027.  
  5028.     move.w    ch_IntMask(a5),d0
  5029.     and.w    d7,d0
  5030.     beq    .not1
  5031.  
  5032.     move.l    ch_RegBase(a5),a0
  5033.     move.l    ch_PerVol(a5),AUDPERVOL(a0)
  5034. ;    move.l    ch_AudPerVol(a5),AUDPERVOL(a0)
  5035. ;    move.l    ch_PerVol(a5),ch_AudPerVol(a5)
  5036.  
  5037.     bsr    DMA_HandleInt
  5038.  
  5039.     move.w    ch_IntMask(a5),custom+INTREQ        ; Clear the interrupt
  5040.     move.l    ch_RegBase(a5),a0
  5041.     move.l    (a6),AUDLC(a0)
  5042.     move.w    ch_DMALength(a5),AUDLEN(a0)
  5043.  
  5044.     clr.b    ch_NoInt(a5)
  5045. .not1
  5046.  
  5047.     add.w    #channel_SIZEOF,a5
  5048.     addq.l    #8,a6
  5049.  
  5050.     move.w    ch_IntMask(a5),d0
  5051.     and.w    d7,d0
  5052.     beq    .not2
  5053.  
  5054.     move.l    ch_RegBase(a5),a0
  5055.     move.l    ch_PerVol(a5),AUDPERVOL(a0)
  5056. ;    move.l    ch_AudPerVol(a5),AUDPERVOL(a0)
  5057. ;    move.l    ch_PerVol(a5),ch_AudPerVol(a5)
  5058.  
  5059.     bsr    DMA_HandleInt
  5060.  
  5061.     move.w    ch_IntMask(a5),custom+INTREQ        ; Clear the interrupt
  5062.     move.l    ch_RegBase(a5),a0
  5063.     move.l    (a6),AUDLC(a0)
  5064.     move.w    ch_DMALength(a5),AUDLEN(a0)
  5065.  
  5066.     clr.b    ch_NoInt(a5)
  5067. .not2
  5068.  
  5069.     add.w    #channel_SIZEOF,a5
  5070.     addq.l    #8,a6
  5071.  
  5072.     move.w    ch_IntMask(a5),d0
  5073.     and.w    d7,d0
  5074.     beq    .not3
  5075.  
  5076.     move.l    ch_RegBase(a5),a0
  5077.     move.l    ch_PerVol(a5),AUDPERVOL(a0)
  5078. ;    move.l    ch_AudPerVol(a5),AUDPERVOL(a0)
  5079. ;    move.l    ch_PerVol(a5),ch_AudPerVol(a5)
  5080.  
  5081.     bsr    DMA_HandleInt
  5082.  
  5083.     move.w    ch_IntMask(a5),custom+INTREQ        ; Clear the interrupt
  5084.     move.l    ch_RegBase(a5),a0
  5085.     move.l    (a6),AUDLC(a0)
  5086.     move.w    ch_DMALength(a5),AUDLEN(a0)
  5087.  
  5088.     clr.b    ch_NoInt(a5)
  5089. .not3
  5090.  
  5091. .exit
  5092.     lea    custom,a0
  5093.     move.w    #DMAF_SETCLR|DMAF_AUDIO,DMACON(a0)    ; Enable DMA
  5094. ;    move.w    #INTF_AUDIO,INTREQ(a0)            ; Clear the interrupts
  5095.  
  5096.     popm    std
  5097.     rts
  5098. * d0-d6 scratch
  5099. * a0-a3 scratch
  5100. * a4    AHIAudioCtrlDrv
  5101. * a5    struct channel *
  5102. * a6    BYTE **buffer[2]
  5103. DMA_HandleInt:
  5104.  
  5105. * Check if the next set of parameters should be fetced
  5106.  
  5107.     cmp.l    #AHIST_NOTYPE,ch_Type(a5)
  5108.     beq    .check_eos
  5109.     tst.b    ch_EndOfSample(a5)            ; Already set?
  5110.     bne    .check_eos
  5111.     move.l    ch_Count(a5),d0
  5112.     beq    .check_eos
  5113.     move.l    ch_Length(a5),d1
  5114.     and.l    #~1,d1                    ; Force even
  5115.     cmp.l    d1,d0
  5116.     blo    .check_eos
  5117.  
  5118. .load_next
  5119.     move.l    ch_NextAddress(a5),ch_Address(a5)
  5120.     move.l    ch_NextLength(a5),ch_Length(a5)
  5121.     move.l    ch_NextType(a5),ch_Type(a5)
  5122.     move.l    ch_NextPerVol(a5),ch_PerVol(a5)
  5123.     move.w    ch_NextScale(a5),ch_Scale(a5)
  5124.     move.l    ch_NextOffset(a5),ch_Offset(a5)
  5125.     clr.l    ch_Count(a5)
  5126.  
  5127.     PRINTF    4,"New sound! %08lx, Length: %ld, Type: %08lx, PerVol: %08lx",ch_Address(a5),ch_Length(a5),ch_Type(a5),ch_PerVol(a5)
  5128.  
  5129.     ; Signal that SoundFunc() should be called
  5130.     st.b    ch_EndOfSample(a5)
  5131.  
  5132.  
  5133. * Check if SoundFunc() should be called
  5134. .check_eos
  5135.     tst.b    ch_EndOfSample(a5)
  5136.     beq    .not_eos
  5137.     clr.b    ch_EndOfSample(a5)            ; Clear signal
  5138.  
  5139.     ; Call the SoundFunc()
  5140.     move.l    ahiac_SoundFunc(a4),d0
  5141.     move.l    d0,a0
  5142.     beq    .nosoundfunc
  5143.     lea    ch_SndMsg(a5),a1
  5144.     move.l    a4,a2
  5145.     move.l    h_Entry(a0),a3
  5146.     moveq    #0,d0
  5147.     move.w    ahism_Channel(a1),d0
  5148.     PRINTF    4,"Calling SoundFunc(%08lx,%08lx,%ld)",a0,a2,d0
  5149.     jsr    (a3)
  5150. .nosoundfunc
  5151. .not_eos
  5152.  
  5153. * Swap chipmem buffers
  5154.     move.l    4(a6),a1
  5155.     move.l    (a6),4(a6)
  5156.     move.l    a1,(a6)
  5157. * Swap cleared indicators
  5158.     move.l    ch_Cleared2(a5),d0
  5159.     move.l    ch_Cleared(a5),ch_Cleared2(a5)
  5160.     move.l    d0,ch_Cleared(a5)
  5161.  
  5162.     move.l    ch_Address(a5),a2
  5163.     moveq    #0,d2
  5164.     move.w    ch_Scale(a5),d2
  5165.  
  5166.     move.l    ch_Length(a5),d0
  5167.     move.l    ch_Count(a5),d1
  5168.  
  5169. * Calculate the number of samples to transfer (this is source samples, which is
  5170. * a multiple of the destination samples if ch_Scale != 0.
  5171.  
  5172.     sub.l    d1,d0
  5173.     ble    .endofsample            ; <= 0 ?
  5174.     tst.w    ch_Period(a5)
  5175.     bne    .normallength
  5176. .endofsample
  5177. * We have either already reached the end of the sample, or it's paused.
  5178. * Set the length to DMABUFFSAMPLES and scale to 0. (I.e., clear the whole
  5179. * chipmem buffer.) Do NOT increase ch_Offset/ch_Count!
  5180.     move.l    #DMABUFFSAMPLES,d0
  5181.     moveq    #0,d2
  5182.     bra    .set_dmalength
  5183. .normallength
  5184.  
  5185.     ; samples = max(samples, DMABUFFSAMPLES*(2^scale))
  5186.     move.l    #DMABUFFSAMPLES,d3
  5187.     lsl.l    d2,d3
  5188.     cmp.l    d3,d0
  5189.     blo    .1
  5190.     move.l    d3,d0
  5191. .1
  5192.     add.l    d0,ch_Count(a5)
  5193.  
  5194. * Get current ch_Offset
  5195.     move.l    ch_Offset(a5),d1
  5196.  
  5197. * Update the ch_Offset
  5198.     move.l    ch_Type(a5),d3
  5199.     and.l    #AHIST_BW,d3
  5200.     beq    .2
  5201.     sub.l    d0,ch_Offset(a5)
  5202.     skipl
  5203. .2
  5204.     add.l    d0,ch_Offset(a5)
  5205.  
  5206. .set_dmalength
  5207.     lsr.l    d2,d0                ; Calc. destination samples
  5208.     move.l    d0,d3
  5209.     lsr.l    #1,d3                ; # of words, round to lower
  5210.     move.w    d3,ch_DMALength(a5)
  5211.  
  5212.     move.l    d2,d3                ;Convert ²log scale...
  5213.     moveq    #0,d2
  5214.     bset    d3,d2                ;...to linear
  5215.  
  5216.     move.l    ch_Type(a5),d3
  5217.  
  5218. * If the period is 0, this sample is paused => clear the buffer
  5219. * If type == AHIST_NOTYPE, clear the buffer
  5220.     tst.w    ch_Period(a5)
  5221.     beq    .clearsample
  5222.     cmp.l    #AHIST_NOTYPE,d3
  5223.     bne    .istype
  5224.  
  5225. .clearsample
  5226.  
  5227. * Alright, we should play silence. But before the dma buffer is filled with
  5228. * zeroes, check if we already have cleared it. In that case, there is no need
  5229. * to do that again (chipmem accesses are expensive!).
  5230.     cmp.l    ch_Cleared(a5),d0
  5231.     bls    .filled                ; Skip it!
  5232.     move.l    d0,ch_Cleared(a5)
  5233.     lea    ClearSample(pc),a3
  5234.     bra    .fill
  5235. .istype
  5236.  
  5237. * It was a normal sample. Figure out which transfer routine to use etc.
  5238.     clr.l    ch_Cleared(a5)            ; Mark buffer as un-cleared
  5239.     move.l    d3,d4
  5240.     and.l    #AHIST_BW,d4
  5241.     beq    .forwardsample
  5242.     neg.l    d2
  5243. .forwardsample
  5244.     and.l    #~AHIST_BW,d3            ; Mask fwd/bwd bit
  5245.     cmp.l    #AHIST_S16S,d3
  5246.     bhi    .error                ; Sanity check!
  5247.     lsl.l    #2,d3
  5248.     move.l    .jmp(pc,d3.l),a3
  5249. .fill
  5250.     jsr    (a3)
  5251. .filled
  5252. .exit
  5253.     rts
  5254.  
  5255. * This should never happen...
  5256. .error
  5257.     PRINTF    2,"Illegal type! %08lx",d3
  5258.     bra    .exit
  5259.  
  5260. .jmp
  5261.     dc.l    CopySampleM8S
  5262.     dc.l    CopySampleM16S
  5263.     dc.l    CopySampleS8S
  5264.     dc.l    CopySampleS16S
  5265.  
  5266. ;in:
  5267. * d0    Samples to copy
  5268. * d1    Source offset
  5269. * d2    Decimate/Scale (not log, but linear, can be negative)
  5270. * a1    Destination
  5271. * a2    Source
  5272. * a5    Channel
  5273.  
  5274. ClearSample:
  5275.     PRINTF    6,"ClearSample %08lx, %ld, %ld",a1,d0,d1
  5276.     addq.l    #3,d0
  5277.     lsr.l    #2,d0                ;Unrolled
  5278.     subq.l    #1,d0
  5279.     bmi    .exit
  5280. .loop
  5281.     clr.l    (a1)+
  5282.     dbf    d0,.loop
  5283. .exit
  5284.     rts
  5285.  
  5286.  
  5287. CopySampleM8S:
  5288.     PRINTF    6,"CopySampleM8S %08lx, %ld, %ld",a1,d0,d1
  5289.     addq.l    #3,d0
  5290.     lsr.l    #2,d0                ;Unrolled
  5291.     subq.l    #1,d0
  5292.     bmi    CopySampleExit
  5293.     add.l    d1,a2
  5294.     cmp.w    #0,a2
  5295.     bne    CopySample
  5296.     bra    CopySampleError
  5297.  
  5298. CopySampleM16S:
  5299.     PRINTF    6,"CopySampleM16S %08lx, %ld, %ld",a1,d0,d1
  5300.     lsl.l    #1,d1                ; 16 bits/sample
  5301.     lsl.l    #1,d2                ; 16 bits/sample
  5302.     addq.l    #3,d0
  5303.     lsr.l    #2,d0                ;Unrolled
  5304.     subq.l    #1,d0
  5305.     bmi    CopySampleExit
  5306.     add.l    d1,a2
  5307.     cmp.w    #0,a2
  5308.     bne    CopySample
  5309.     bra    CopySampleError
  5310.  
  5311. CopySampleS8S:
  5312.     PRINTF    6,"CopySampleS8S %08lx, %ld, %ld",a1,d0,d1
  5313.     lsl.l    #1,d1                ; 16 bits/sample frame
  5314.     lsl.l    #1,d2                ; 16 bits/sample frame
  5315.     addq.l    #3,d0
  5316.     lsr.l    #2,d0                ;Unrolled
  5317.     subq.l    #1,d0
  5318.     bmi    CopySampleExit
  5319.     add.l    d1,a2
  5320.     cmp.w    #0,a2
  5321.     beq    CopySampleError
  5322.     add.w    ch_Stereo(a5),a2
  5323.     bra    CopySample
  5324.  
  5325. CopySampleS16S:
  5326.     PRINTF    6,"CopySampleS16S %08lx, %ld, %ld",a1,d0,d1
  5327.     lsl.l    #2,d1                ; 32 bits/sample frame
  5328.     lsl.l    #2,d2                ; 32 bits/sample frame
  5329.     addq.l    #3,d0
  5330.     lsr.l    #2,d0                ;Unrolled
  5331.     subq.l    #1,d0
  5332.     bmi    CopySampleExit
  5333.     add.l    d1,a2
  5334.     cmp.w    #0,a2
  5335.     beq    CopySampleError
  5336.     add.w    ch_Stereo(a5),a2
  5337.     add.w    ch_Stereo(a5),a2
  5338.     bra    CopySample
  5339.  
  5340. CopySampleExit:
  5341.     rts
  5342.  
  5343. CopySampleError
  5344.     PRINTF    2,"CopySampleError"
  5345.     bra    CopySampleExit
  5346.  
  5347. * Collect 4 samples and write a full longword to the chipmem buffer
  5348. CopySample:
  5349. .loop
  5350.     move.b    (a2),d3
  5351.     add.l    d2,a2
  5352.     lsl.l    #8,d3
  5353.     move.b    (a2),d3
  5354.     add.l    d2,a2
  5355.     lsl.l    #8,d3
  5356.     move.b    (a2),d3
  5357.     add.l    d2,a2
  5358.     lsl.l    #8,d3
  5359.     move.b    (a2),d3
  5360.     add.l    d2,a2
  5361.     move.l    d3,(a1)+
  5362.     dbf    d0,.loop
  5363.     rts
  5364. EndCode:
  5365. @
  5366.  
  5367.  
  5368. 4.19
  5369. log
  5370. @Recording didn't work in all modes!
  5371. @
  5372. text
  5373. @d3 1
  5374. a3 1
  5375. * $Id: paula_audio.a,v 4.18 1998/02/09 00:41:36 lcs Exp lcs $
  5376. d5 3
  5377. d196 2
  5378. a199 1
  5379.     UWORD    p_Pad0
  5380. d954 4
  5381. d1496 9
  5382. @
  5383.  
  5384.  
  5385. 4.18
  5386. log
  5387. @Fixed a interrupt problem (playback could touch record's enable bits!).
  5388. @
  5389. text
  5390. @d3 1
  5391. a3 1
  5392. * $Id: paula_audio.a,v 4.17 1998/01/10 19:47:33 lcs Exp lcs $
  5393. d5 3
  5394. d857 1
  5395. a857 1
  5396.     and.b    #~(PF_14BIT|PF_DMA),d0
  5397. d1890 1
  5398. d1892 1
  5399. a1892 1
  5400.     and.b    #~(PF_14BIT|PF_DMA),d0
  5401. @
  5402.  
  5403.  
  5404. 4.17
  5405. log
  5406. @Alright, the DMA version is ready for release.
  5407. @
  5408. text
  5409. @d3 1
  5410. a3 1
  5411. * $Id: paula_audio.a,v 4.16 1997/12/02 09:28:28 lcs Exp $
  5412. d5 3
  5413. d191 2
  5414. d623 3
  5415. a630 1
  5416.     PRINTF    2,"H"
  5417. d940 1
  5418. d1100 1
  5419. d1148 2
  5420. d1464 1
  5421. d1585 1
  5422. d1625 1
  5423. d1630 1
  5424. a1630 6
  5425.     btst.b    #PB_DMA,p_Flags(a3)
  5426.     beq    .mixing
  5427.     move.w    #INTF_SETCLR|INTF_AUDIO,custom+INTENA
  5428.     bra    .exit
  5429. .mixing
  5430.     move.w    #INTF_SETCLR|INTF_AUD0,custom+INTENA
  5431. d1814 2
  5432. d1874 1
  5433. d1982 1
  5434. d2252 1
  5435. d2319 1
  5436. d2343 3
  5437. a2345 2
  5438.     move.w    #INTF_AUDIO,INTENA(a4)
  5439.     move.w    #INTF_AUDIO,INTREQ(a4)        ;Clear any waiting interrupts
  5440. d2382 1
  5441. d2520 1
  5442. d2894 1
  5443. d4227 1
  5444. d4250 1
  5445. d4290 1
  5446. d4456 1
  5447. a4457 1
  5448.     PRINTF    2,"AHIsub_SetFreq()"
  5449. d4551 1
  5450. a4552 1
  5451.     PRINTF    2,"AHIsub_SetSound()"
  5452. a4652 1
  5453.  
  5454. @
  5455.  
  5456.  
  5457. 4.16
  5458. log
  5459. @Fixed all known problems in the DMA mode.
  5460. @
  5461. text
  5462. @d3 5
  5463. a7 2
  5464. * $Id: $
  5465. * $Log: $
  5466. d34 2
  5467. a35 8
  5468. VERSION        EQU    4
  5469. REVISION    EQU    16
  5470. DATE    MACRO
  5471.         dc.b    "30.11.97"
  5472.     ENDM
  5473. VERS    MACRO
  5474.         dc.b    "paula.audio 4.16"
  5475.     ENDM
  5476. d4871 1
  5477. d4937 2
  5478. d4959 2
  5479. d4981 2
  5480. @
  5481.  
  5482.  
  5483. 4.15
  5484. log
  5485. @Added a DMA mode (beta).
  5486. @
  5487. text
  5488. @d5 3
  5489. d32 1
  5490. a32 1
  5491. REVISION    EQU    15
  5492. d34 1
  5493. a34 1
  5494.         dc.b    "22.11.97"
  5495. d37 1
  5496. a37 1
  5497.         dc.b    "paula.audio 4.15ß"
  5498. d58 1
  5499. a63 1
  5500.     include    libraries/realtime.i
  5501. d74 1
  5502. a74 1
  5503.     include    lvo/realtime_lib.i
  5504. d96 1
  5505. d125 1
  5506. a125 1
  5507.     APTR    pb_RealTimeLib
  5508. d139 1
  5509. a139 2
  5510.     UWORD    ch_Pad2
  5511.     ULONG    ch_Offset            ;Where are we playing?
  5512. d142 5
  5513. d150 4
  5514. a153 1
  5515.     ULONG    ch_Length            ;Current sample length
  5516. d161 1
  5517. a161 1
  5518.     UWORD    ch_Volume            ;Next period
  5519. d163 2
  5520. a164 2
  5521.     UWORD    ch_NextPeriod            ;Current volume
  5522.     UWORD    ch_NextVolume            ;Next volume
  5523. d166 6
  5524. a171 1
  5525.     UWORD    ch_Scale            ;Current frequency scale
  5526. d192 1
  5527. a192 1
  5528.     APTR    p_UtilityBase            ;(DMA only)
  5529. d259 13
  5530. a271 4
  5531.     APTR    p_RTPlayer            ;realtime.library Player (DMA only)
  5532.     STRUCT    p_RTPlayerHook,h_SIZEOF
  5533.     ULONG    p_RTTimeStamp
  5534.     
  5535. d308 1
  5536. a308 1
  5537. realtimeName:    dc.b    "realtime.library",0
  5538. a395 6
  5539.     lea    realtimeName(pc),a1
  5540.     moveq    #0,d0
  5541.     call    OpenLibrary
  5542.     move.l    d0,pb_RealTimeLib(a5)
  5543.     ; Don't fail if the library couldn't be opened.
  5544.  
  5545. a440 3
  5546.     move.l    pb_RealTimeLib(a5),a1
  5547.     call    CloseLibrary
  5548.  
  5549. d493 4
  5550. d621 1
  5551. a621 1
  5552.     pushm    d2-d7/a2-a6
  5553. d638 1
  5554. d643 1
  5555. a643 1
  5556.     move.l    pb_UtilLib(a5),p_UtilityBase(a3)
  5557. d650 1
  5558. d1057 1
  5559. a1057 1
  5560.     popm    d2-d7/a2-a6
  5561. d1095 1
  5562. a1095 1
  5563.     pushm    d2-d7/a2-a6
  5564. d1130 1
  5565. a1130 1
  5566.     popm    d2-d7/a2-a6
  5567. d1142 1
  5568. a1142 1
  5569.     pushm    d2-d7/a2-a6
  5570. d1269 1
  5571. a1269 1
  5572.     popm    d2-d7/a2-a6
  5573. d1456 1
  5574. a1456 1
  5575.     pushm    d2-d7/a2-a6
  5576. d1541 1
  5577. a1541 1
  5578.     popm    d2-d7/a2-a6
  5579. d1572 1
  5580. a1572 1
  5581. * MUST NOT REFERENCE a6!! (See RealTimePlayer()!)
  5582. d1611 1
  5583. a1611 1
  5584. * MUST NOT REFERENCE a6!! (See RealTimePlayer()!)
  5585. d1808 1
  5586. a1808 1
  5587.     pushm    d2-d7/a2-a6
  5588. d1980 1
  5589. a1980 1
  5590.     popm    d2-d7/a2-a6
  5591. d2242 1
  5592. a2242 1
  5593.     pushm    d2-d7/a2-a6
  5594. d2254 1
  5595. a2254 1
  5596. ;; Save PlayerFreq somewhere if required!
  5597. d2273 1
  5598. a2273 1
  5599.     popm    d2-d7/a2-a6
  5600. d2308 1
  5601. a2308 1
  5602.     pushm    d2-d7/a2-a6
  5603. d2395 1
  5604. a2395 1
  5605.     popm    d2-d7/a2-a6
  5606. d2506 1
  5607. a2506 1
  5608.     pushm    d2-d7/a2-a6
  5609. d2546 1
  5610. a2546 1
  5611.     popm    d2-d7/a2-a6
  5612. d2638 1
  5613. a2638 1
  5614.     moveq    #FALSE,d0
  5615. d4114 1
  5616. d4138 1
  5617. d4157 1
  5618. a4157 3
  5619.     move.l    pb_RealTimeLib(a5),d0
  5620.     move.l    d0,a6
  5621.     beq    .norealtime
  5622. d4159 2
  5623. a4160 3
  5624.     lea    RealTimePlayer(pc),a0
  5625.     move.l    a0,p_RTPlayerHook+h_Entry(a3)
  5626.     move.l    a3,p_RTPlayerHook+h_Data(a3)
  5627. d4162 24
  5628. a4185 20
  5629.     move.l    sp,d2
  5630.     pea    TAG_DONE
  5631.     pea    (a2)
  5632.     pea    PLAYER_UserData
  5633.     pea    TRUE
  5634.     pea    PLAYER_Ready
  5635.     pea    ~0
  5636.     pea    PLAYER_Conductor
  5637.     pea    127
  5638.     pea    PLAYER_Priority
  5639.     pea    p_RTPlayerHook(a3)
  5640.     pea    PLAYER_Hook
  5641.     pea    LibName(pc)
  5642.     pea    PLAYER_Name
  5643.     move.l    sp,a0
  5644.     call    CreatePlayerA
  5645.     move.l    d2,sp
  5646.     tst.l    d0
  5647.     move.l    d0,p_RTPlayer(a3)
  5648.     beq    .norealtime
  5649. d4187 2
  5650. a4188 1
  5651.     clr.l    p_RTTimeStamp(a3)
  5652. d4190 20
  5653. a4209 6
  5654.     move.l    p_RTPlayer(a3),a0
  5655.     moveq    #CONDSTATE_RUNNING,d0
  5656.     move.l    p_RTTimeStamp(a3),d1
  5657.     call    SetConductorState
  5658.     tst.l    d0
  5659.     bne    .norealtime
  5660. d4218 1
  5661. a4218 1
  5662. .norealtime
  5663. d4227 34
  5664. d4276 2
  5665. a4277 3
  5666.     move.l    pb_RealTimeLib(a5),d0
  5667.     move.l    d0,a6
  5668.     beq    .norealtime
  5669. d4279 1
  5670. a4279 3
  5671.     move.l    p_RTPlayer(a3),a0
  5672.     clr.l    p_RTPlayer(a3)
  5673.     call    DeletePlayer
  5674. d4281 9
  5675. a4289 1
  5676. .norealtime
  5677. d4291 2
  5678. a4292 1
  5679.     move.l    #Interrupt_Dummy,IS_CODE+p_PlayInt(a3)
  5680. d4295 8
  5681. d4317 1
  5682. a4317 3
  5683.     move.l    p_DMAbuffer(a3),d0
  5684.     beq.b    .nodmamem
  5685.     move.l    d0,a1
  5686. a4319 1
  5687. .nodmamem
  5688. d4386 12
  5689. a4397 1
  5690.     move.w    d1,ch_NextVolume(a0)
  5691. d4401 12
  5692. d4414 1
  5693. a4414 2
  5694.     move.w    d1,AUDVOL(a1)
  5695.     move.w    d1,ch_Volume(a0)
  5696. d4453 1
  5697. a4453 1
  5698.     moveq    #1,d3            ; Decimate/scale
  5699. d4494 1
  5700. a4550 1
  5701.     add.l    so_Address(a1),d2
  5702. d4558 7
  5703. d4569 2
  5704. a4570 1
  5705.     move.l    d2,ch_NextAddress(a0)
  5706. d4578 2
  5707. a4579 1
  5708.     move.l    d2,ch_Address(a0)
  5709. d4582 1
  5710. a4582 1
  5711.     clr.l    ch_Offset(a0)
  5712. d4634 10
  5713. a4643 1
  5714.     bra    AHIsub_NoDMA
  5715. d4646 1
  5716. a4646 1
  5717.  
  5718. d4650 54
  5719. d4780 1
  5720. a4780 3
  5721. * a0    Hook
  5722. * a1    message, currently pmTime or pmState
  5723. * a2    address of Player structure
  5724. d4782 2
  5725. a4783 2
  5726. RealTimePlayer:
  5727.     pushm    d2/a2-a3
  5728. d4785 2
  5729. a4786 2
  5730.     cmp.l    #PM_TICK,pmt_Method(a1)
  5731.     bne    .exit
  5732. d4788 3
  5733. a4790 1
  5734.     move.l    h_Data(a0),a0            ; Get struct paula *
  5735. d4792 2
  5736. a4793 4
  5737. .loop
  5738.     move.l    p_RTTimeStamp(a0),d2
  5739.     cmp.l    pmt_Time(a1),d2
  5740.     bhi    .exit                ; Exit if pmt_Time < p_RTTimeStamp
  5741. d4795 2
  5742. a4796 4
  5743.     move.l    p_AudioCtrl(a0),a2
  5744.     move.l    ahiac_PlayerFreq(a2),d1
  5745.     beq    .exit                ; Sanity check
  5746.     move.l    #TICK_FREQ<<16,d0
  5747. d4798 6
  5748. a4803 8
  5749.  IFGE    __CPU-68020
  5750.     divu.l    d1,d0
  5751.  ELSE
  5752.     push    a0
  5753.     move.l    p_UtilityBase(a0),a0
  5754.     jsr    _LVOUDivMod32(a0)
  5755.     pop    a0
  5756.  ENDIF
  5757. d4805 17
  5758. a4821 1
  5759.     move.l    d2,p_RTTimeStamp(a0)        ; p_RTTimeStamp = p_RTTimeStamp + TICK_FREQ/PlayerFreq
  5760. d4823 12
  5761. a4834 1
  5762.     PRINTF    8,"RTP: %ld", pmt_Time(a1)
  5763. a4835 1
  5764.     pushm    a0/a1
  5765. d4838 26
  5766. d4865 1
  5767. d4870 1
  5768. a4870 1
  5769.     move.l    h_Entry(a0),a3
  5770. d4872 1
  5771. a4872 1
  5772.     jsr    (a3)
  5773. a4874 2
  5774.     popm    a0/a1
  5775.     bra    .loop
  5776. a4876 1
  5777.     popm    d2/a2-a3
  5778. d4878 1
  5779. d4892 1
  5780. a4892 1
  5781.     pushm    d0-a6
  5782. d4907 3
  5783. a4909 2
  5784.     move.w    ch_Period(a5),AUDPER(a0)
  5785.     move.w    ch_Volume(a5),AUDVOL(a0)
  5786. a4918 4
  5787.  
  5788.     moveq    #0,d0
  5789.     move.w    ch_DMALength(a5),d0
  5790.     PRINTF    6,"#0: Addr: %08lx (%ld) Length: %ld, PerVol: %08lx", (a6), ch_Offset(a5), d0, ch_PerVol(a5)
  5791. d4929 3
  5792. a4931 2
  5793.     move.w    ch_Period(a5),AUDPER(a0)
  5794.     move.w    ch_Volume(a5),AUDVOL(a0)
  5795. a4938 4
  5796.  
  5797.     moveq    #0,d0
  5798.     move.w    ch_DMALength(a5),d0
  5799.     PRINTF    6,"#1: Addr: %08lx (%ld) Length: %ld, PerVol: %08lx", (a6), ch_Offset(a5), d0, ch_PerVol(a5)
  5800. d4949 3
  5801. a4951 2
  5802.     move.w    ch_Period(a5),AUDPER(a0)
  5803.     move.w    ch_Volume(a5),AUDVOL(a0)
  5804. a4958 4
  5805.  
  5806.     moveq    #0,d0
  5807.     move.w    ch_DMALength(a5),d0
  5808.     PRINTF    6,"#2: Addr: %08lx (%ld) Length: %ld, PerVol: %08lx", (a6), ch_Offset(a5), d0, ch_PerVol(a5)
  5809. d4969 3
  5810. a4971 2
  5811.     move.w    ch_Period(a5),AUDPER(a0)
  5812.     move.w    ch_Volume(a5),AUDVOL(a0)
  5813. a4978 4
  5814.  
  5815.     moveq    #0,d0
  5816.     move.w    ch_DMALength(a5),d0
  5817.     PRINTF    6,"#3: Addr: %08lx (%ld) Length: %ld, PerVol: %08lx", (a6), ch_Offset(a5), d0, ch_PerVol(a5)
  5818. d4986 1
  5819. a4986 3
  5820.     popm    d0-a6
  5821.  
  5822.  
  5823. d4988 2
  5824. a4989 1
  5825.  
  5826. d4995 1
  5827. a4995 5
  5828.  
  5829.     tst.b    ch_EndOfSample(a5)
  5830.     beq    .0
  5831. ;    PRINTF    0,"New sound!"
  5832. .0
  5833. d4998 5
  5834. a5002 3
  5835.     beq    .act
  5836.     move.l    ch_Offset(a5),d0
  5837.     beq    .act
  5838. d5004 1
  5839. a5004 1
  5840.     bclr    #0,d1                    ; Force even
  5841. d5006 1
  5842. a5006 1
  5843.     blo    .act
  5844. d5008 1
  5845. d5014 2
  5846. a5015 1
  5847.     clr.l    ch_Offset(a5)
  5848. d5019 1
  5849. a5021 1
  5850. .act
  5851. d5023 2
  5852. d5027 1
  5853. a5027 1
  5854.     clr.b    ch_EndOfSample(a5)
  5855. d5043 1
  5856. a5043 1
  5857. ;Swap buffers
  5858. d5047 8
  5859. d5057 4
  5860. a5060 1
  5861.     move.l    ch_Offset(a5),d1
  5862. d5063 1
  5863. a5063 1
  5864.     beq    .endofsample
  5865. d5065 1
  5866. a5065 1
  5867.     bne    .advance
  5868. d5067 3
  5869. a5069 2
  5870.     PRINTF    6,"Length == 0 or Freq == 0"
  5871.     move.w    #DMABUFFSAMPLES>>1,ch_DMALength(a5)
  5872. d5071 3
  5873. a5073 1
  5874.     bra    .2
  5875. d5075 4
  5876. a5078 2
  5877. .advance
  5878.     cmp.l    #DMABUFFSAMPLES,d0
  5879. d5080 1
  5880. a5080 1
  5881.     move.l    #DMABUFFSAMPLES,d0
  5882. d5082 12
  5883. a5093 3
  5884.     lsr.l    #1,d0                ; # of words, round to lower
  5885.     move.w    d0,ch_DMALength(a5)
  5886.     lsl.l    #1,d0
  5887. a5094 1
  5888. .2
  5889. d5096 5
  5890. a5100 2
  5891.     move.l    ch_Address(a5),a2
  5892.     move.w    ch_Scale(a5),d2
  5893. d5102 3
  5894. a5104 5
  5895.     tst.w    ch_Period(a5)
  5896.     bne    .notpaused
  5897.     lea    ClearSample(pc),a3
  5898.     bra    .fill
  5899. .notpaused
  5900. d5108 4
  5901. d5114 9
  5902. d5127 8
  5903. d5141 1
  5904. d5145 1
  5905. d5159 1
  5906. a5159 1
  5907. * d2.w    Decimate/Scale
  5908. d5167 1
  5909. a5167 1
  5910.     lsr.l    #2,d0
  5911. d5180 1
  5912. a5180 1
  5913.     lsr.l    #2,d0
  5914. d5182 1
  5915. a5182 1
  5916.     bmi    .exit
  5917. d5185 2
  5918. a5186 20
  5919.     beq    .error
  5920. .loop
  5921.     move.b    (a2),d3
  5922.     add.w    d2,a2
  5923.     lsl.l    #8,d3
  5924.     move.b    (a2),d3
  5925.     add.w    d2,a2
  5926.     lsl.l    #8,d3
  5927.     move.b    (a2),d3
  5928.     add.w    d2,a2
  5929.     lsl.l    #8,d3
  5930.     move.b    (a2),d3
  5931.     add.w    d2,a2
  5932.     move.l    d3,(a1)+
  5933.     dbf    d0,.loop
  5934. .exit
  5935.     rts
  5936. .error
  5937.     PRINTF    2,"Error!
  5938.     bra    .exit
  5939. d5191 1
  5940. a5191 1
  5941.     lsl.w    #1,d2                ; 16 bits/sample
  5942. d5193 1
  5943. a5193 1
  5944.     lsr.l    #2,d0
  5945. d5195 1
  5946. a5195 1
  5947.     bmi    .exit
  5948. d5198 2
  5949. a5199 20
  5950.     beq    .error
  5951. .loop
  5952.     move.b    (a2),d3
  5953.     add.w    d2,a2
  5954.     lsl.l    #8,d3
  5955.     move.b    (a2),d3
  5956.     add.w    d2,a2
  5957.     lsl.l    #8,d3
  5958.     move.b    (a2),d3
  5959.     add.w    d2,a2
  5960.     lsl.l    #8,d3
  5961.     move.b    (a2),d3
  5962.     add.w    d2,a2
  5963.     move.l    d3,(a1)+
  5964.     dbf    d0,.loop
  5965. .exit
  5966.     rts
  5967. .error
  5968.     PRINTF    2,"Error!
  5969.     bra    .exit
  5970. d5204 1
  5971. a5204 1
  5972.     lsl.w    #1,d2                ; 16 bits/sample frame
  5973. d5206 1
  5974. a5206 1
  5975.     lsr.l    #2,d0
  5976. d5208 1
  5977. a5208 1
  5978.     bmi    .exit
  5979. d5211 1
  5980. a5211 1
  5981.     beq    .error
  5982. d5213 1
  5983. a5213 19
  5984. .loop
  5985.     move.b    (a2),d3
  5986.     add.w    d2,a2
  5987.     lsl.l    #8,d3
  5988.     move.b    (a2),d3
  5989.     add.w    d2,a2
  5990.     lsl.l    #8,d3
  5991.     move.b    (a2),d3
  5992.     add.w    d2,a2
  5993.     lsl.l    #8,d3
  5994.     move.b    (a2),d3
  5995.     add.w    d2,a2
  5996.     move.l    d3,(a1)+
  5997.     dbf    d0,.loop
  5998. .exit
  5999.     rts
  6000. .error
  6001.     PRINTF    2,"Error!
  6002.     bra    .exit
  6003. d5218 1
  6004. a5218 1
  6005.     lsl.w    #2,d2                ; 32 bits/sample frame
  6006. d5220 1
  6007. a5220 1
  6008.     lsr.l    #2,d0
  6009. d5222 1
  6010. a5222 1
  6011.     bmi    .exit
  6012. d5225 1
  6013. a5225 1
  6014.     beq    .exit
  6015. d5228 11
  6016. d5241 1
  6017. a5241 1
  6018.     add.w    d2,a2
  6019. d5244 1
  6020. a5244 1
  6021.     add.w    d2,a2
  6022. d5247 1
  6023. a5247 1
  6024.     add.w    d2,a2
  6025. d5250 1
  6026. a5250 1
  6027.     add.w    d2,a2
  6028. a5252 1
  6029. .exit
  6030. a5253 4
  6031. .error
  6032.     PRINTF    2,"Error!
  6033.     bra    .exit
  6034.  
  6035. @
  6036.  
  6037.  
  6038. 4.14
  6039. log
  6040. @Enclosed FindTask("Picasso96") with Forbid()/Permit(), in order to
  6041.     silence PatchWork.
  6042. @
  6043. text
  6044. @d5 4
  6045. d29 1
  6046. a29 1
  6047. REVISION    EQU    14
  6048. d31 1
  6049. a31 1
  6050.         dc.b    "20.8.97"
  6051. d34 1
  6052. a34 1
  6053.         dc.b    "paula.audio 4.14"
  6054. d60 1
  6055. d71 1
  6056. d85 11
  6057. d100 2
  6058. d108 1
  6059. d121 1
  6060. d126 44
  6061. d176 2
  6062. a177 3
  6063.     ULONG    p_MinBufferLength
  6064.     APTR    p_DMAbuffer            ;Chipmem play buffer
  6065.     APTR    p_CalibrationTable
  6066. d179 5
  6067. a183 1
  6068.     ULONG    p_DoubleBufferOffset
  6069. d185 2
  6070. a186 2
  6071.     UWORD    p_SwapChannels
  6072.     UWORD    p_Pad1
  6073. d188 1
  6074. a188 3
  6075. ; Pointers to chipmem play buffer
  6076.  
  6077.     LABEL    p_AudPtrs
  6078. d198 17
  6079. a214 19
  6080.     UWORD    p_AudPer
  6081.     UWORD    p_OutputVolume
  6082.     UWORD    p_MonitorVolume
  6083.     UWORD    p_Input
  6084.  
  6085.     APTR    p_AudioCtrl
  6086.  
  6087.     APTR    p_audioport
  6088.     APTR    p_audioreq
  6089.     ULONG    p_audiodev
  6090.     APTR    p_ParBitsUser
  6091.     APTR    p_ParPortUser
  6092.     APTR    p_SerBitsUser
  6093.     APTR    p_CardHandle
  6094.  
  6095.     STRUCT    p_PlayInt,IS_SIZE
  6096.     STRUCT    p_PlaySoftInt,IS_SIZE
  6097.     STRUCT    p_RecInt,IS_SIZE
  6098.     STRUCT    p_RecSoftInt,IS_SIZE
  6099. d216 1
  6100. a216 1
  6101.     ULONG    p_LoopTimes
  6102. d218 1
  6103. a218 1
  6104.     LABEL    p_PlayerHookRegs
  6105. d223 1
  6106. a223 1
  6107.     LABEL    p_MixHookRegs
  6108. d228 3
  6109. a230 4
  6110.     LABEL    p_RecIntDataAura
  6111.     APTR    p_AuraAddress
  6112.  
  6113.     LABEL    p_RecIntData
  6114. d238 1
  6115. a238 1
  6116.     LABEL    p_RecordMessage
  6117. d243 9
  6118. a251 1
  6119.     STRUCT    p_CalibrationArray,256
  6120. d259 1
  6121. d283 1
  6122. d371 6
  6123. d422 3
  6124. d465 1
  6125. d470 7
  6126. d494 1
  6127. a494 1
  6128. *       order to allow enhancements, please only use bit 0 to 3 for modes!
  6129. d512 1
  6130. d536 1
  6131. d553 1
  6132. d606 2
  6133. d622 1
  6134. a630 1
  6135.     moveq    #0,d2
  6136. d632 4
  6137. d637 1
  6138. a637 1
  6139.     moveq    #0,d1
  6140. d642 1
  6141. a642 1
  6142.     moveq    #PF_14BIT,d2
  6143. d645 1
  6144. a645 1
  6145.     moveq    #0,d1
  6146. d652 9
  6147. a660 3
  6148.     move.l    ahiac_Flags(a2),d0
  6149.     and.b    #PF_STEREO,d0            ;same as AHIACF_STEREO
  6150.     or.b    d2,d0
  6151. d662 2
  6152. a663 2
  6153.     and.b    #~(PF_STEREO|PF_HIFI|PF_14BIT),d1
  6154.     or.b    d0,d1
  6155. d666 11
  6156. d809 17
  6157. d827 3
  6158. a829 2
  6159.     btst    #PB_14BIT,p_Flags(a3)
  6160.     bne    .dontgetsampler            ;no record if 14 bit mode
  6161. d884 1
  6162. d913 1
  6163. a913 1
  6164.     move.w    #INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3,custom+INTENA
  6165. d952 80
  6166. d1033 1
  6167. d1042 2
  6168. d1065 1
  6169. d1074 1
  6170. a1074 7
  6171.     move.l    #PALFREQ,d2            ;PAL
  6172.     move.l    pb_GfxLib(a5),a0
  6173.     move.w    gb_DisplayFlags(a0),d0
  6174.     btst    #REALLY_PALn,d0
  6175.     bne.b    .1
  6176.     move.l    #NTSCFREQ,d2            ;NTSC
  6177. .1
  6178. d1443 6
  6179. d1454 1
  6180. d1550 1
  6181. d1557 1
  6182. a1557 1
  6183.     move.w    #INTF_AUD0,custom+INTENA
  6184. d1561 1
  6185. d1589 1
  6186. d1596 6
  6187. a1601 1
  6188.     bne.b    .exit
  6189. d1607 1
  6190. d1718 2
  6191. a1719 2
  6192. *       card or by using 'realtime.library'. No other Amiga resources may
  6193. *       be used for timing (like direct CIA timers).
  6194. d1726 5
  6195. a1730 5
  6196. *       own timing hardware or 'realtime.library' may be used. Note that
  6197. *       ahiac_MixerFunc, ahiac_BuffSamples, ahiac_MinBuffSamples,
  6198. *       ahiac_MaxBuffSamples and ahiac_BuffSize are undefined. ahiac_MixFreq
  6199. *       is the frequency the user wants to use for recording, if you support
  6200. *       that.
  6201. d1805 6
  6202. d1856 2
  6203. a1857 1
  6204.     btst    #PB_14BIT,p_Flags(a3)        ;Sanity check...
  6205. d2179 1
  6206. d2193 2
  6207. a2194 1
  6208. *       Mixing & timing: ahiac_PlayerFunc, ahiac_MixerFunc, ahiac_SamplerFunc,
  6209. d2196 2
  6210. a2197 1
  6211. *       Mixing only: ahiac_PlayerFunc, ahiac_MixerFunc, ahiac_SamplerFunc and
  6212. d2199 2
  6213. a2200 1
  6214. *       Nothing: ahiac_PlayerFunc, ahiac_SamplerFunc and ahiac_PlayerFreq.
  6215. d2230 6
  6216. a2243 16
  6217.     PRINTF    2,"LoopTimes: %ld", d0
  6218.  
  6219. ;    move.l    p_MinBufferLength(a3),d0
  6220. ;    divu.w    d1,d0
  6221. ;    ext.l    d0
  6222. ;    move.l    d0,p_RepeatTimes(a3)    ;that's really times-1 (dbf dx,label)
  6223.  
  6224. ;    PRINTF    2,"RepeatTimes: %ld", d0
  6225.  
  6226. ;    addq.l    #1,d0
  6227. ;    mulu.w    d1,d0
  6228. ;    lsr.l    #1,d0            ;length in words
  6229. ;    move.w    d0,p_AudLen(a3)
  6230.  
  6231. ;    PRINTF    2,"AudLen: %ld", d0
  6232.  
  6233. d2248 1
  6234. d2300 7
  6235. d2309 2
  6236. a2310 2
  6237.     move.w    #INTF_AUD0,INTENA(a4)
  6238.     move.w    #INTF_AUD0,INTREQ(a4)        ;Clear any waiting interrupts
  6239. d2334 1
  6240. d2371 1
  6241. a2371 1
  6242. .return
  6243. a2375 49
  6244. ****** [driver].audio/AHIsub_#? *********************************************
  6245. *
  6246. *   NAME
  6247. *       AHIsub_SetEffect -- Set effect.
  6248. *       AHIsub_SetFreq -- Set frequency.
  6249. *       AHIsub_SetSound -- Set sound.
  6250. *       AHIsub_SetVol -- Set volume and stereo panning.
  6251. *       AHIsub_LoadSound -- Prepare a sound for playback.
  6252. *       AHIsub_UnloadSound -- Discard a sound.
  6253. *
  6254. *   SYNOPSIS
  6255. *       See functions in 'ahi.device'.
  6256. *
  6257. *   IMPLEMENTATION
  6258. *       If AHIsub_AllocAudio() did not return with bit AHISB_MIXING set,
  6259. *       all user calls to these function will be routed to the driver.
  6260. *
  6261. *       If AHIsub_AllocAudio() did return with bit AHISB_MIXING set, the
  6262. *       calls will first be routed to the driver, and only handled by
  6263. *       'ahi.device' if the driver returned AHIS_UNKNOWN. This way it is
  6264. *       possible to add effects that the sound card handles on its own, like
  6265. *       filter and echo effects.
  6266. *
  6267. *       For what each function does, see the autodocs for 'ahi.device'.
  6268. *
  6269. *   INPUTS
  6270. *       See functions in 'ahi.device'.
  6271. *
  6272. *   NOTES
  6273. *       See functions in 'ahi.device'.
  6274. *
  6275. *   SEE ALSO
  6276. *       ahi.device/AHI_SetEffect(), ahi.device/AHI_SetFreq(),
  6277. *       ahi.device/AHI_SetSound(), ahi.device/AHI_SetVol(),
  6278. *       ahi.device/AHI_LoadSound(), ahi.device/AHI_UnloadSound()
  6279. *       
  6280. *
  6281. *****************************************************************************
  6282. *
  6283. *
  6284.  
  6285. AHIsub_SetVol:
  6286. AHIsub_SetFreq:
  6287. AHIsub_SetSound:
  6288. AHIsub_SetEffect:
  6289. AHIsub_LoadSound:
  6290. AHIsub_UnloadSound:
  6291.     moveq    #AHIS_UNKNOWN,d0
  6292.     rts
  6293. d2397 1
  6294. d2400 3
  6295. a2402 1
  6296. *           AHIDB_MaxChannels - Return the resulting number of channels.
  6297. d2405 1
  6298. d2407 1
  6299. a2407 1
  6300. *               Example: You support 3 frequencies 32, 44.1 and 48 kHz.
  6301. d2409 1
  6302. d2412 1
  6303. a2412 1
  6304. *               Example: You support 3 frequencies 32, 44.1 and 48 kHz.
  6305. d2414 1
  6306. d2417 1
  6307. d2420 1
  6308. d2423 1
  6309. d2426 1
  6310. d2428 1
  6311. d2430 1
  6312. d2432 1
  6313. d2435 1
  6314. d2441 1
  6315. d2446 1
  6316. d2451 1
  6317. d2455 1
  6318. d2460 1
  6319. d2465 1
  6320. d2485 1
  6321. d2490 3
  6322. d2494 3
  6323. a2496 3
  6324.     moveq    #FALSE,d3
  6325.     move.l    a1,a0
  6326.     move.l    a1,d0
  6327. d2498 1
  6328. d2503 7
  6329. d2511 1
  6330. d2535 5
  6331. a2539 5
  6332.     dc.w    0                ; AHIDB_Volume
  6333.     dc.w    0                ; AHIDB_Panning
  6334.     dc.w    0                ; AHIDB_Stereo
  6335.     dc.w    0                ; AHIDB_HiFi
  6336.     dc.w    0                ; AHIDB_PingPong
  6337. d2543 1
  6338. a2543 1
  6339.     dc.w    0                ; AHIDB_MaxChannels
  6340. d2576 44
  6341. d2628 8
  6342. d2640 2
  6343. d2647 3
  6344. d2654 1
  6345. d2661 12
  6346. a2674 2
  6347. ;    move.l    (a0,d1.w),d1
  6348. ;    bsr    calcperiod
  6349. d2723 2
  6350. d2738 2
  6351. d2756 2
  6352. d2771 2
  6353. d2820 1
  6354. d2918 1
  6355. d2922 1
  6356. a2922 1
  6357.     move.w    #INTF_AUD0|INTF_AUD1|INTF_AUD2|INTF_AUD3,INTREQ(a0)
  6358. a2925 3
  6359. *******************************************************************************
  6360. *******************************************************************************
  6361.  
  6362. d4069 972
  6363. @
  6364.  
  6365.  
  6366. 4.13
  6367. log
  6368. @Rewrote the conversion routines, they should be faster now?
  6369. Added the AHIpaulaBufferLength environment variable.
  6370. There were errors in the new conversion routines, when the tempo changed.
  6371. 8 bit modes now have hardware volume control.
  6372. Added the AHIpaulaSwapChannels environment variable.
  6373. AHIsub_GetAttr() is much faster now.
  6374. @
  6375. text
  6376. @d5 8
  6377. d25 3
  6378. a27 3
  6379. REVISION    EQU    13
  6380. DATE    MACRO    
  6381.         dc.b    "27.7.97"
  6382. d30 1
  6383. a30 1
  6384.         dc.b    "paula.audio 4.13"
  6385. d987 1
  6386. d989 1
  6387. a989 1
  6388.     move.l    pb_SysLib(a5),a6
  6389. d991 1
  6390. d1130 1
  6391. a1130 1
  6392.         
  6393. d1162 1
  6394. a1162 1
  6395.         
  6396. a2277 8
  6397.  IFGE    __CPU-68020
  6398.     tst.l    a1
  6399.  ELSE
  6400.      cmp.l    #0,a1
  6401.  ENDC
  6402.     beq    .notaglist            ;no tag list!
  6403.  
  6404.     move.l    a1,a3
  6405. d2280 4
  6406. a2283 1
  6407.  
  6408. d2285 1
  6409. a2285 2
  6410.     moveq    #FALSE,d1
  6411.     move.l    a3,a0
  6412. d2287 3
  6413. a2289 2
  6414.     tst.l    d0
  6415.     bne    .2
  6416. d2291 8
  6417. a2298 2
  6418. * Only for AHIDB_Paula14Bit FALSE (== recording available)
  6419.     popm    d0-d1
  6420. d2300 3
  6421. a2302 61
  6422.     cmp.l    #AHIDB_Record,d0
  6423.     bne.b    .not_record1
  6424.     moveq    #TRUE,d0
  6425.     bra    .exit
  6426. .not_record1
  6427.     cmp.l    #AHIDB_FullDuplex,d0
  6428.     bne.b    .not_fullduplex1
  6429.     moveq    #TRUE,d0
  6430.     bra    .exit
  6431. .not_fullduplex1
  6432.     cmp.l    #AHIDB_MaxRecordSamples,d0
  6433.     bne.b    .not_mrs1
  6434.     move.l    #RECORDSAMPLES,d0
  6435.     bra    .exit
  6436. .not_mrs1
  6437.     cmp.l    #AHIDB_MinMonitorVolume,d0
  6438.     bne.b    .not_minmonvol1
  6439.     moveq    #0,d0
  6440.     bra    .exit
  6441. .not_minmonvol1
  6442.     cmp.l    #AHIDB_MaxMonitorVolume,d0
  6443.     bne.b    .not_maxmonvol1
  6444.     move.l    #$10000,d0
  6445.     bra    .exit
  6446. .not_maxmonvol1
  6447.     cmp.l    #AHIDB_MinOutputVolume,d0
  6448.     bne.b    .not_minoutvol1
  6449.     moveq    #0,d0
  6450.     bra    .exit
  6451. .not_minoutvol1
  6452.     cmp.l    #AHIDB_MaxOutputVolume,d0
  6453.     bne.b    .not_maxoutvol1
  6454.     move.l    #$10000,d0
  6455.     bra    .exit
  6456. .not_maxoutvol1
  6457.     cmp.l    #AHIDB_MinInputGain,d0
  6458.     bne.b    .not_mingain1
  6459.     move.l    #$10000,d0
  6460.     bra    .exit
  6461. .not_mingain1
  6462.     cmp.l    #AHIDB_MaxInputGain,d0
  6463.     bne.b    .not_maxgain1
  6464.     move.l    #$10000,d0
  6465.     bra    .exit
  6466. .not_maxgain1
  6467.     cmp.l    #AHIDB_Inputs,d0
  6468.     bne.b    .not_inputs
  6469.     moveq    #3,d0
  6470.     bra    .exit
  6471. .not_inputs
  6472.     cmp.l    #AHIDB_Input,d0
  6473.     bne.b    .not_input
  6474.     lsl.l    #2,d1
  6475.     move.l    .inputs(pc,d1.w),d0
  6476.     bra    .exit
  6477. .not_input
  6478.     bra    .3
  6479. .inputs:
  6480.     dc.l    .input0
  6481.     dc.l    .input1
  6482.     dc.l    .input2
  6483. d2304 2
  6484. a2305 11
  6485. .2
  6486. * Only for AHIDB_Paula14Bit TRUE (== no recording)
  6487.     popm    d0-d1
  6488.     cmp.l    #AHIDB_Record,d0
  6489.     bne.b    .not_record2
  6490.     moveq    #FALSE,d0
  6491.     bra    .exit
  6492. .not_record2
  6493.     cmp.l    #AHIDB_FullDuplex,d0
  6494.     bne.b    .not_fullduplex2
  6495.     moveq    #FALSE,d0
  6496. a2306 1
  6497. .not_fullduplex2
  6498. d2308 44
  6499. a2351 2
  6500. .3
  6501. * Common tags (AHIDB_14bit)
  6502. d2353 1
  6503. a2353 8
  6504.     cmp.l    #AHIDB_Bits,d0
  6505.     bne.b    .not_bits
  6506.     move.l    #AHIDB_Paula14Bit,d0
  6507.     moveq    #FALSE,d1
  6508.     move.l    a3,a0
  6509.     call    GetTagData
  6510.     tst.l    d0
  6511.     beq.b    .no14bit
  6512. d2355 2
  6513. a2356 2
  6514.     skipw
  6515. .no14bit
  6516. d2358 12
  6517. a2369 5
  6518.     bra    .exit
  6519. .not_bits
  6520. .notaglist
  6521.     cmp.l    #AHIDB_Frequencies,d0
  6522.     bne.b    .not_freqs
  6523. d2372 6
  6524. a2377 7
  6525.     beq.b    .f
  6526.     move.l    #FREQUENCIES,d0
  6527.     bra    .exit
  6528. .f
  6529.     move.l    #FREQUENCIES_OCS,d0
  6530.     bra    .exit
  6531. .not_freqs
  6532. d2379 2
  6533. a2380 4
  6534.     cmp.l    #AHIDB_Frequency,d0
  6535.     bne.b    .not_freq
  6536.     add.w    d1,d1
  6537.     add.w    d1,d1
  6538. d2385 3
  6539. a2387 11
  6540.     bra    .exit
  6541. .not_freq
  6542.     cmp.l    #AHIDB_Index,d0
  6543.     bne.b    .not_index
  6544.     move.l    d1,d0
  6545.     bsr    findfreq
  6546.     move.l    d1,d0
  6547.     bra    .exit
  6548. .not_index
  6549.     cmp.l    #AHIDB_Author,d0
  6550.     bne.b    .not_author
  6551. d2390 5
  6552. a2394 4
  6553.     bra    .exit
  6554. .not_author
  6555.     cmp.l    #AHIDB_Copyright,d0
  6556.     bne.b    .not_copyright
  6557. d2397 5
  6558. a2401 4
  6559.     bra    .exit
  6560. .not_copyright
  6561.     cmp.l    #AHIDB_Version,d0
  6562.     bne.b    .not_version
  6563. d2404 3
  6564. a2406 4
  6565.     bra    .exit
  6566. .not_version
  6567.     cmp.l    #AHIDB_Annotation,d0
  6568.     bne.b    .not_anno
  6569. d2409 23
  6570. a2431 4
  6571.     bra    .exit
  6572. .not_anno
  6573.     cmp.l    #AHIDB_Realtime,d0
  6574.     bne.b    .not_realtime
  6575. d2433 36
  6576. a2468 13
  6577.     bra    .exit
  6578. .not_realtime
  6579.     cmp.l    #AHIDB_Outputs,d0
  6580.     bne.b    .not_outputs
  6581.     moveq    #1,d0
  6582.     bra    .exit
  6583. .not_outputs
  6584.     cmp.l    #AHIDB_Output,d0
  6585.     bne.b    .not_output
  6586.     lea    .output(pc),a0
  6587.     move.l    a0,d0
  6588.     bra    .exit
  6589. .not_output
  6590. d2470 5
  6591. a2474 2
  6592. * Unknown attribute, return default.
  6593.     move.l    d2,d0
  6594. a2475 1
  6595.     popm    d2-d7/a2-a6
  6596. d2477 9
  6597. a2485 3
  6598. .author        dc.b    "Martin 'Leviticus' Blom",0
  6599. .copyright    dc.b    "Public Domain",0
  6600. .anno        dc.b    "14 bit routines by Christian Buchner.",0
  6601. d2489 10
  6602. @
  6603.  
  6604.  
  6605. 4.10
  6606. log
  6607. @Initial RCS'ed version.
  6608. @
  6609. text
  6610. @d5 3
  6611. a10 4
  6612. *  There is still room for improvements in the softint's. For example,
  6613. * try if reducing chip memory accesses increases speed. Not high priority, though.
  6614. *  This driver should probably have a DMA play mode for 1-4 stereo channels.
  6615. *
  6616. d12 1
  6617. a12 2
  6618. * there are lots of clicks. But still, I have tried to sample at 22kHz while down-
  6619. * loading files from a BBS on my A4000/040, and it worked without any serial errors.
  6620. d17 1
  6621. a17 1
  6622. REVISION    EQU    10
  6623. d19 1
  6624. a19 1
  6625.         dc.b    "23.5.97"
  6626. d22 1
  6627. a22 1
  6628.         dc.b    "paula.audio 4.10"
  6629. d66 2
  6630. a76 12
  6631.  IFD    BARFLY
  6632.   IFD    MC020
  6633.     MC68020
  6634.   ENDC
  6635.  ELSE
  6636.   IFD    MC020
  6637.     auto    wo AHI:user/devs/ahi/paula.audio\
  6638.   ELSE    
  6639.     auto    wo AHI:user/devs/ahi/paula.audio.000\
  6640.   ENDC
  6641.  ENDC    * BARFLY
  6642.  
  6643. d100 31
  6644. a130 2
  6645.     UBYTE    p_Parallel            ;TRUE if pport allocated
  6646.     UWORD    p_DisableCount
  6647. a133 1
  6648.     APTR    p_DMAbuffer
  6649. d144 1
  6650. a144 17
  6651.     UWORD    p_MonitorVolume
  6652.     UWORD    p_Input
  6653.  
  6654. *** IS_DATA for Play Interrupt (do not change order!)
  6655.     LABEL    p_PlayIntData
  6656.     APTR    p_PlaySoftIntPtr
  6657.     UWORD    p_AudLen            ;don't change order
  6658.     UWORD    p_AudPer            ;
  6659.     ULONG    p_DoubleBufferFlag
  6660.     APTR    p_AudPtr1A
  6661.     APTR    p_AudPtr2A
  6662.     APTR    p_AudPtr3A
  6663.     APTR    p_AudPtr4A
  6664.     APTR    p_AudPtr1B
  6665.     APTR    p_AudPtr2B
  6666.     APTR    p_AudPtr3B
  6667.     APTR    p_AudPtr4B
  6668. d146 1
  6669. a146 2
  6670. *** IS_DATA for Play Software Interrupt (do not change order!)
  6671.     LABEL    p_PlaySoftIntData
  6672. a148 1
  6673.     APTR    p_AudioCtrlP
  6674. d150 2
  6675. a151 3
  6676.     FPTR    p_PreTimer
  6677.     FPTR    p_PostTimer
  6678.     ULONG    p_LoopTimes
  6679. a153 1
  6680.     APTR    p_AudioCtrlM
  6681. a154 2
  6682.     APTR    p_AudPtrs
  6683.     APTR    p_CalibrationTable
  6684. a155 1
  6685. *** IS_DATA for Aura Record Interrupt (do not change order!)
  6686. d158 1
  6687. a158 1
  6688. *** IS_DATA for Paula Record Interrupt (do not change order!)
  6689. d162 1
  6690. a162 1
  6691.     UWORD    p_Pad3
  6692. d207 2
  6693. d519 1
  6694. a519 4
  6695.     move.l    a2,p_AudioCtrlP(a3)        ;player Hook
  6696.     move.l    a2,p_AudioCtrlM(a3)        ;mixer Hook
  6697.     lea    p_PlaySoftInt(a3),a0
  6698.     move.l    a0,p_PlaySoftIntPtr(a3)
  6699. d524 1
  6700. d603 45
  6701. d748 1
  6702. a748 2
  6703.     lea    p_PlayIntData(a3),a1
  6704.     move.l    a1,IS_DATA+p_PlayInt(a3)
  6705. d754 1
  6706. a754 2
  6707.     lea    p_PlaySoftIntData(a3),a1
  6708.     move.l    a1,IS_DATA+p_PlaySoftInt(a3)
  6709. d1417 1
  6710. a1417 1
  6711. *          It is always filled with signed 16-bit (32 bit if AHIDBB_HIFI in
  6712. d1432 1
  6713. a1432 1
  6714. *          Note that neither AHIDBB_STEREO nor AHIDBB_HIFI will be set if
  6715. d1553 1
  6716. a1553 1
  6717.     btst    #AHISB_PLAY,d0
  6718. d1576 3
  6719. a1578 2
  6720. * The init*bit? routines allocates p_DMAbuffer, sets up p_AudPtr, sets the volume,
  6721. * stores the correct interrupt routines in p_PlayInt's and p_PlaySoftInt's IS_CODE.
  6722. d1640 3
  6723. a1642 2
  6724.     move.w    p_MonitorVolume(a3),AUD2VOL(a4)
  6725.     move.w    p_MonitorVolume(a3),AUD3VOL(a4)
  6726. d1729 1
  6727. d1738 4
  6728. a1741 3
  6729.     move.l    ahiac_MaxBuffSamples(a2),d0    ;Max. # of 8 bit samples
  6730.     addq.l    #1,d0
  6731.     bclr    #0,d0                ;force even
  6732. d1756 2
  6733. a1757 2
  6734.     move.w    #64,AUD0VOL(a4)
  6735.     move.w    #64,AUD1VOL(a4)
  6736. d1771 1
  6737. d1780 4
  6738. a1783 3
  6739.     move.l    ahiac_MaxBuffSamples(a2),d0    ;Max. # of 8 bit samples
  6740.     addq.l    #1,d0
  6741.     bclr    #0,d0                ;force even
  6742. d1800 2
  6743. a1801 2
  6744.     move.w    #64,AUD0VOL(a4)
  6745.     move.w    #64,AUD1VOL(a4)
  6746. d1815 1
  6747. d1834 4
  6748. a1837 3
  6749.     move.l    ahiac_MaxBuffSamples(a2),d0    ;Max. # of 16 bit samples
  6750.     addq.l    #1,d0
  6751.     bclr    #0,d0                ;force even
  6752. d1858 4
  6753. a1861 4
  6754.     move.w    #64,AUD0VOL(a4)
  6755.     move.w    #64,AUD1VOL(a4)
  6756.     move.w    #1,AUD2VOL(a4)
  6757.     move.w    #1,AUD3VOL(a4)
  6758. d1875 1
  6759. d1894 4
  6760. a1897 3
  6761.     move.l    ahiac_MaxBuffSamples(a2),d0    ;Max. # of 16 bit samples
  6762.     addq.l    #1,d0
  6763.     bclr    #0,d0                ;force even
  6764. d1922 4
  6765. a1925 4
  6766.     move.w    #64,AUD0VOL(a4)
  6767.     move.w    #64,AUD1VOL(a4)
  6768.     move.w    #1,AUD2VOL(a4)
  6769.     move.w    #1,AUD3VOL(a4)
  6770. d1980 5
  6771. a1984 3
  6772.     move.l    ahiac_BuffSamples(a2),d0
  6773.     lsr.l    #1,d0            ;length in words, force even # of samples
  6774.     move.w    d0,p_AudLen(a3)
  6775. d1988 16
  6776. a2007 3
  6777.     move.l    ahiac_PreTimer(a2),p_PreTimer(a3)
  6778.     move.l    ahiac_PostTimer(a2),p_PostTimer(a3)
  6779.  
  6780. a2058 5
  6781.     moveq    #0,d0
  6782.     move.w    d0,AUD0VOL(a4)
  6783.     move.w    d0,AUD1VOL(a4)
  6784.     move.w    d0,AUD2VOL(a4)
  6785.     move.w    d0,AUD3VOL(a4)
  6786. d2068 6
  6787. d2268 1
  6788. a2268 1
  6789.  IFD    MC020
  6790. d2314 10
  6791. d2463 1
  6792. a2463 1
  6793. .input2        dc.b    "Clarity sampler",0.
  6794. d2539 17
  6795. d2582 2
  6796. a2583 1
  6797. ;----------------------------------------------------------------------------
  6798. d2590 3
  6799. d2595 1
  6800. a2595 1
  6801. * d1    INTENAR && INTREQR
  6802. d2597 1
  6803. a2597 1
  6804. * a1    &(paulaBase->p_RecIntData)
  6805. d2608 1
  6806. a2608 1
  6807.  IFD    MC020
  6808. d2634 1
  6809. a2634 1
  6810. * d1    INTENAR && INTREQR
  6811. d2636 1
  6812. a2636 1
  6813. * a1    &(paulaBase->p_RecIntData)
  6814. d2686 1
  6815. a2686 1
  6816. * d1    INTENAR && INTREQR
  6817. d2688 1
  6818. a2688 1
  6819. * a1    &(paulaBase->p_RecIntDataAura)
  6820. d2692 4
  6821. d2715 2
  6822. d2734 1
  6823. a2734 1
  6824. * a1    paulaBase
  6825. d2741 3
  6826. a2743 2
  6827.     move.w    p_MonitorVolume(a1),custom+AUD2VOL
  6828.     move.w    p_MonitorVolume(a1),custom+AUD3VOL
  6829. d2745 1
  6830. a2745 1
  6831.     move.l    p_AudioCtrlP(a1),a2
  6832. d2753 3
  6833. d2758 1
  6834. a2758 1
  6835. * d1    INTENAR && INTREQR
  6836. d2760 1
  6837. a2760 1
  6838. * a1    &(paulaBase->p_PlayIntData)
  6839. d2765 22
  6840. a2786 7
  6841.     movem.l    (a1)+,d0/d1            ;p_PlaySoftIntPtr,p_AudLen/p_AudPer
  6842.     move.l    d1,AUD0LEN(a0)
  6843.     move.l    d1,AUD1LEN(a0)
  6844.     not.l    (a1)+                ;double buffering
  6845.     lea    p_AudPtrs-p_AudPtr1A(a1),a5
  6846.     beq.b    .1
  6847.     add.w    #4*4,a1
  6848. d2788 1
  6849. a2788 4
  6850.     move.l    a1,(a5)
  6851.     move.l    (a1)+,AUD0LC(a0)
  6852.     move.l    (a1)+,AUD1LC(a0)
  6853.     move.l    d0,a1                ;p_PlaySoftInt
  6854. d2792 1
  6855. d2794 32
  6856. a2825 9
  6857.     movem.l    (a1)+,d0/d1            ;p_PlaySoftIntPtr,p_AudLen/p_AudPer
  6858.     move.l    d1,AUD0LEN(a0)
  6859.     move.l    d1,AUD1LEN(a0)
  6860.     move.l    d1,AUD2LEN(a0)
  6861.     move.l    d1,AUD3LEN(a0)
  6862.     not.l    (a1)+                ;double buffering
  6863.     lea    p_AudPtrs-p_AudPtr1A(a1),a5
  6864.     beq.b    .1
  6865.     add.w    #4*4,a1
  6866. d2827 1
  6867. a2827 6
  6868.     move.l    a1,(a5)
  6869.     move.l    (a1)+,AUD0LC(a0)
  6870.     move.l    (a1)+,AUD1LC(a0)
  6871.     move.l    (a1)+,AUD2LC(a0)
  6872.     move.l    (a1)+,AUD3LC(a0)
  6873.     move.l    d0,a1                ;p_PlaySoftInt
  6874. d2831 3
  6875. d2838 1
  6876. a2838 1
  6877. * a1    &(paulaBase->p_PlaySoftIntData)
  6878. d2841 15
  6879. a2855 4
  6880. SoftInt_8bitM:
  6881.     pushm    a2/a3/a4/a6
  6882.     move.l    a1,a5
  6883.     movem.l    (a5)+,a0/a1/a2/a3/a4/a6
  6884. d2857 3
  6885. a2859 3
  6886.     jsr    (a4)                ;call PreTimer
  6887.     bne    .exit
  6888.     movem.l    (a5),d0/a0/a1/a2/a3/a5
  6889. d2861 37
  6890. d2899 5
  6891. a2903 2
  6892. * convert and transfer buffer
  6893.     move.l    (a5),a0
  6894. d2905 9
  6895. a2913 3
  6896.     move.b    (a1),(a0)+
  6897.     move.b    2(a1),(a0)+
  6898.     addq.l    #4,a1
  6899. d2915 8
  6900. a2922 4
  6901. .exit
  6902.     jsr    (a6)                ;call PostTimer, a2 ok
  6903.     popm    a2/a3/a4/a6
  6904.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1,custom+DMACON
  6905. d2925 1
  6906. a2925 6
  6907. ;in:
  6908. * d0    scratch
  6909. * d1    scratch
  6910. * a0    scratch
  6911. * a1    &(paulaBase->p_PlaySoftIntData)
  6912. * a5    scratch
  6913. d2928 1
  6914. a2928 8
  6915.     pushm    a2/a3/a4/a6
  6916.     move.l    a1,a5
  6917.     movem.l    (a5)+,a0/a1/a2/a3/a4/a6
  6918.     jsr    (a3)                ;call Player Hook
  6919.     jsr    (a4)                ;call PreTimer
  6920.     bne    .exit
  6921.     movem.l    (a5),d0/a0/a1/a2/a3/a5
  6922.     jsr    (a3)                ;call Mixer Hook
  6923. d2930 1
  6924. a2930 2
  6925. * convert and transfer buffer
  6926.     move.l    (a5),a0
  6927. d2932 9
  6928. a2940 3
  6929.     move.b    (a1),(a0)+
  6930.     move.b    4(a1),(a0)+
  6931.     addq.l    #8,a1
  6932. d2942 8
  6933. a2949 4
  6934. .exit
  6935.     jsr    (a6)                ;call PostTimer, a2 ok
  6936.     popm    a2/a3/a4/a6
  6937.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1,custom+DMACON
  6938. d2952 1
  6939. a2952 6
  6940. ;in:
  6941. * d0    scratch
  6942. * d1    scratch
  6943. * a0    scratch
  6944. * a1    &(paulaBase->p_PlaySoftIntData)
  6945. * a5    scratch
  6946. d2955 1
  6947. a2955 8
  6948.     pushm    a2/a3/a4/a6
  6949.     move.l    a1,a5
  6950.     movem.l    (a5)+,a0/a1/a2/a3/a4/a6
  6951.     jsr    (a3)                ;call Player Hook
  6952.     jsr    (a4)                ;call PreTimer
  6953.     bne    .exit
  6954.     movem.l    (a5),d0/a0/a1/a2/a3/a5
  6955.     jsr    (a3)                ;call Mixer Hook
  6956. d2957 2
  6957. a2958 2
  6958. * convert and transfer buffer
  6959.     movem.l    (a5),a0/a3
  6960. d2960 22
  6961. a2981 7
  6962.  REPT    2
  6963. ;left
  6964.     move.b    (a1),(a3)+
  6965. ;right
  6966.     move.b    2(a1),(a0)+
  6967.     addq.l    #4,a1
  6968.  ENDR
  6969. d2983 9
  6970. a2991 4
  6971. .exit
  6972.     jsr    (a6)                ;call PostTimer, a2 ok
  6973.     popm    a2/a3/a4/a6
  6974.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1,custom+DMACON
  6975. d2994 1
  6976. a2994 6
  6977. ;in:
  6978. * d0    scratch
  6979. * d1    scratch
  6980. * a0    scratch
  6981. * a1    &(paulaBase->p_PlaySoftIntData)
  6982. * a5    scratch
  6983. d2997 1
  6984. a2997 8
  6985.     pushm    a2/a3/a4/a6
  6986.     move.l    a1,a5
  6987.     movem.l    (a5)+,a0/a1/a2/a3/a4/a6
  6988.     jsr    (a3)                ;call Player Hook
  6989.     jsr    (a4)                ;call PreTimer
  6990.     bne    .exit
  6991.     movem.l    (a5),d0/a0/a1/a2/a3/a5
  6992.     jsr    (a3)                ;call Mixer Hook
  6993. d2999 2
  6994. a3000 2
  6995. * convert and transfer buffer
  6996.     movem.l    (a5),a0/a3
  6997. d3002 22
  6998. a3023 7
  6999.  REPT    2
  7000. ;left
  7001.     move.b    (a1),(a3)+
  7002. ;right
  7003.     move.b    4(a1),(a0)+
  7004.     addq.l    #8,a1
  7005.  ENDR
  7006. d3025 9
  7007. a3033 4
  7008. .exit
  7009.     jsr    (a6)                ;call PostTimer, a2 ok
  7010.     popm    a2/a3/a4/a6
  7011.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1,custom+DMACON
  7012. d3036 1
  7013. a3036 6
  7014. ;in:
  7015. * d0    scratch
  7016. * d1    scratch
  7017. * a0    scratch
  7018. * a1    &(paulaBase->p_PlaySoftIntData)
  7019. * a5    scratch
  7020. d3039 1
  7021. a3039 8
  7022.     pushm    a2/a3/a4/a6
  7023.     move.l    a1,a5
  7024.     movem.l    (a5)+,a0/a1/a2/a3/a4/a6
  7025.     jsr    (a3)                ;call Player Hook
  7026.     jsr    (a4)                ;call PreTimer
  7027.     bne    .exit
  7028.     movem.l    (a5),d0/a0/a1/a2/a3/a5
  7029.     jsr    (a3)                ;call Mixer Hook
  7030. d3041 2
  7031. a3042 2
  7032. * convert and transfer buffer
  7033.     movem.l    (a5),a0/a3/a4/a5        ;a3/a4 unused
  7034. d3044 19
  7035. a3062 3
  7036.  REPT    2
  7037.     move.b    (a1)+,(a0)+
  7038.     move.b    (a1)+,d1
  7039. d3064 6
  7040. a3069 2
  7041.     move.b    d1,(a5)+
  7042.  ENDR
  7043. d3071 11
  7044. a3081 4
  7045. .exit
  7046.     jsr    (a6)                ;call PostTimer, a2 ok
  7047.     popm    a2/a3/a4/a6
  7048.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,custom+DMACON
  7049. d3084 2
  7050. a3085 6
  7051. ;in:
  7052. * d0    scratch
  7053. * d1    scratch
  7054. * a0    scratch
  7055. * a1    &(paulaBase->p_PlaySoftIntData)
  7056. * a5    scratch
  7057. d3088 1
  7058. a3088 8
  7059.     pushm    a2/a3/a4/a6
  7060.     move.l    a1,a5
  7061.     movem.l    (a5)+,a0/a1/a2/a3/a4/a6
  7062.     jsr    (a3)                ;call Player Hook
  7063.     jsr    (a4)                ;call PreTimer
  7064.     bne    .exit
  7065.     movem.l    (a5),d0/a0/a1/a2/a3/a5
  7066.     jsr    (a3)                ;call Mixer Hook
  7067. d3090 2
  7068. a3091 2
  7069. * convert and transfer buffer
  7070.     movem.l    (a5),a0/a3/a4/a5        ;a3/a4 unused
  7071. d3093 26
  7072. a3118 7
  7073.  REPT    2
  7074.     move.b    (a1)+,(a0)+
  7075.     move.b    (a1)+,d1
  7076.     lsr.b    #2,d1
  7077.     move.b    d1,(a5)+
  7078.     addq.l    #2,a1
  7079.  ENDR
  7080. d3120 11
  7081. a3130 4
  7082. .exit
  7083.     jsr    (a6)                ;call PostTimer, a2 ok
  7084.     popm    a2/a3/a4/a6
  7085.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,custom+DMACON
  7086. d3133 1
  7087. a3133 6
  7088. ;in:
  7089. * d0    scratch
  7090. * d1    scratch
  7091. * a0    scratch
  7092. * a1    &(paulaBase->p_PlaySoftIntData)
  7093. * a5    scratch
  7094. d3136 1
  7095. a3136 8
  7096.     pushm    a2/a3/a4/a6
  7097.     move.l    a1,a5
  7098.     movem.l    (a5)+,a0/a1/a2/a3/a4/a6
  7099.     jsr    (a3)                ;call Player Hook
  7100.     jsr    (a4)                ;call PreTimer
  7101.     bne    .exit
  7102.     movem.l    (a5),d0/a0/a1/a2/a3/a4/a5
  7103.     jsr    (a3)                ;call Mixer Hook
  7104. d3138 4
  7105. a3141 4
  7106. * convert and transfer buffer, using the table
  7107.     move.l    (a4),a0
  7108.     move.l    12(a4),a4
  7109.     moveq    #0,d1
  7110. d3144 29
  7111. a3172 4
  7112.  REPT    2
  7113.  IFD    MC020
  7114.     move.w    (a1)+,d1            ;fetch 16 bit sample
  7115.     move.w    (a5,d1.l*2),d1
  7116. d3174 25
  7117. a3198 9
  7118.     moveq    #0,d1
  7119.     move.w    (a1)+,d1            ;fetch 16 bit sample
  7120.      add.w    d1,d1
  7121.      move.w    (a5,d1.l),d1
  7122.  ENDC
  7123.      move.b    d1,(a4)+            ;low byte
  7124.      lsr.w    #8,d1
  7125.      move.b    d1,(a0)+            ;high byte
  7126.  ENDR
  7127. d3200 11
  7128. a3210 4
  7129. .exit
  7130.     jsr    (a6)                ;call PostTimer, a2 ok
  7131.     popm    a2/a3/a4/a6
  7132.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,custom+DMACON
  7133. d3213 1
  7134. a3213 6
  7135. ;in:
  7136. * d0    scratch
  7137. * d1    scratch
  7138. * a0    scratch
  7139. * a1    &(paulaBase->p_PlaySoftIntData)
  7140. * a5    scratch
  7141. d3216 1
  7142. a3216 8
  7143.     pushm    a2/a3/a4/a6
  7144.     move.l    a1,a5
  7145.     movem.l    (a5)+,a0/a1/a2/a3/a4/a6
  7146.     jsr    (a3)                ;call Player Hook
  7147.     jsr    (a4)                ;call PreTimer
  7148.     bne    .exit
  7149.     movem.l    (a5),d0/a0/a1/a2/a3/a4/a5
  7150.     jsr    (a3)                ;call Mixer Hook
  7151. d3218 4
  7152. a3221 4
  7153. * convert and transfer buffer, using the table
  7154.     move.l    (a4),a0
  7155.     move.l    12(a4),a4
  7156.     moveq    #0,d1
  7157. d3224 16
  7158. a3239 4
  7159.  REPT    2
  7160.  IFD    MC020
  7161.     move.w    (a1)+,d1            ;fetch 16 bit sample
  7162.     move.w    (a5,d1.l*2),d1
  7163. d3241 39
  7164. a3279 10
  7165.     moveq    #0,d1
  7166.     move.w    (a1)+,d1            ;fetch 16 bit sample
  7167.      add.w    d1,d1
  7168.      move.w    (a5,d1.l),d1
  7169.  ENDC
  7170.      move.b    d1,(a4)+            ;low byte
  7171.      lsr.w    #8,d1
  7172.      move.b    d1,(a0)+            ;high byte
  7173.      addq.l    #2,a1
  7174.  ENDR
  7175. d3281 11
  7176. a3291 4
  7177. .exit
  7178.     jsr    (a6)                ;call PostTimer, a2 ok
  7179.     popm    a2/a3/a4/a6
  7180.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,custom+DMACON
  7181. d3294 2
  7182. a3295 6
  7183. ;in:
  7184. * d0    scratch
  7185. * d1    scratch
  7186. * a0    scratch
  7187. * a1    &(paulaBase->p_PlaySoftIntData)
  7188. * a5    scratch
  7189. d3298 6
  7190. a3303 12
  7191.     pushm    a2/a3/a4/a6
  7192.     move.l    a1,a5
  7193.     movem.l    (a5)+,a0/a1/a2/a3/a4/a6
  7194.     jsr    (a3)                ;call Player Hook
  7195.     jsr    (a4)                ;call PreTimer
  7196.     bne    .exit
  7197.     movem.l    (a5),d0/a0/a1/a2/a3/a5
  7198.     jsr    (a3)                ;call Mixer Hook
  7199.     push    a2
  7200. * convert and transfer buffer
  7201. * TODO: Use a table!
  7202.     movem.l    (a5),a0/a2/a3/a5
  7203. d3305 22
  7204. a3326 9
  7205.  REPT    2
  7206. ;left
  7207.     move.b    (a1)+,(a2)+
  7208.     move.b    (a1)+,d1
  7209.     lsr.b    #2,d1
  7210.     move.b    d1,(a3)+
  7211. ;right
  7212.     move.b    (a1)+,(a0)+
  7213.     move.b    (a1)+,d1
  7214. d3328 27
  7215. a3354 2
  7216.     move.b    d1,(a5)+
  7217.  ENDR
  7218. d3356 13
  7219. a3368 5
  7220.     pop    a2
  7221. .exit
  7222.     jsr    (a6)                ;call PostTimer, a2 ok
  7223.     popm    a2/a3/a4/a6
  7224.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,custom+DMACON
  7225. d3371 1
  7226. a3371 6
  7227. ;in:
  7228. * d0    scratch
  7229. * d1    scratch
  7230. * a0    scratch
  7231. * a1    &(paulaBase->p_PlaySoftIntData)
  7232. * a5    scratch
  7233. d3374 6
  7234. a3379 12
  7235.     pushm    a2/a3/a4/a6
  7236.     move.l    a1,a5
  7237.     movem.l    (a5)+,a0/a1/a2/a3/a4/a6
  7238.     jsr    (a3)                ;call Player Hook
  7239.     jsr    (a4)                ;call PreTimer
  7240.     bne    .exit
  7241.     movem.l    (a5),d0/a0/a1/a2/a3/a5
  7242.     jsr    (a3)                ;call Mixer Hook
  7243.     push    a2
  7244. * convert and transfer buffer
  7245. * TODO: Use a table!
  7246.     movem.l    (a5),a0/a2/a3/a5
  7247. d3381 50
  7248. a3430 14
  7249.  REPT    2
  7250. ;left
  7251.     move.b    (a1)+,(a2)+
  7252.     move.b    (a1)+,d1
  7253.     lsr.b    #2,d1
  7254.     move.b    d1,(a3)+
  7255.     addq.l    #2,a1
  7256. ;right
  7257.     move.b    (a1)+,(a0)+
  7258.     move.b    (a1)+,d1
  7259.     lsr.b    #2,d1
  7260.     move.b    d1,(a5)+
  7261.     addq.l    #2,a1
  7262.  ENDR
  7263. d3432 13
  7264. a3444 5
  7265.     pop    a2
  7266. .exit
  7267.     jsr    (a6)                ;call PostTimer, a2 ok
  7268.     popm    a2/a3/a4/a6
  7269.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,custom+DMACON
  7270. d3447 2
  7271. a3448 6
  7272. ;in:
  7273. * d0    scratch
  7274. * d1    scratch
  7275. * a0    scratch
  7276. * a1    &(paulaBase->p_PlaySoftIntData)
  7277. * a5    scratch
  7278. d3451 9
  7279. a3459 12
  7280.     pushm    a2/a3/a4/a6
  7281.     move.l    a1,a5
  7282.     movem.l    (a5)+,a0/a1/a2/a3/a4/a6
  7283.     jsr    (a3)                ;call Player Hook
  7284.     jsr    (a4)                ;call PreTimer
  7285.     bne    .exit
  7286.     movem.l    (a5),d0/a0/a1/a2/a3/a4/a5
  7287.     jsr    (a3)                ;call Mixer Hook
  7288.     push    a2
  7289. * convert and transfer buffer, using the table
  7290.     movem.l    (a4),a0/a2/a3/a4
  7291.     moveq    #0,d1
  7292. a3460 1
  7293.  REPT    2
  7294. d3462 60
  7295. a3521 4
  7296. ;left
  7297.  IFD    MC020
  7298.     move.w    (a1)+,d1            ;fetch 16 bit sample
  7299.     move.w    (a5,d1.l*2),d1
  7300. d3523 38
  7301. a3560 13
  7302.     moveq    #0,d1
  7303.     move.w    (a1)+,d1            ;fetch 16 bit sample
  7304.      add.w    d1,d1
  7305.      move.w    (a5,d1.l),d1
  7306.  ENDC
  7307.      move.b    d1,(a3)+            ;low byte
  7308.      lsr.w    #8,d1
  7309.      move.b    d1,(a2)+            ;high byte
  7310.  
  7311. ;right
  7312.  IFD    MC020
  7313.     move.w    (a1)+,d1            ;fetch 16 bit sample
  7314.     move.w    (a5,d1.l*2),d1
  7315. d3562 12
  7316. a3573 9
  7317.     moveq    #0,d1
  7318.     move.w    (a1)+,d1            ;fetch 16 bit sample
  7319.      add.w    d1,d1
  7320.      move.w    (a5,d1.l),d1
  7321.  ENDC
  7322.      move.b    d1,(a4)+            ;low byte
  7323.      lsr.w    #8,d1
  7324.      move.b    d1,(a0)+            ;high byte
  7325.  ENDR
  7326. d3576 14
  7327. a3589 5
  7328.     pop    a2
  7329. .exit
  7330.     jsr    (a6)                ;call PostTimer
  7331.     popm    a2/a3/a4/a6
  7332.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,custom+DMACON
  7333. d3592 2
  7334. a3593 6
  7335. ;in:
  7336. * d0    scratch
  7337. * d1    scratch
  7338. * a0    scratch
  7339. * a1    &(paulaBase->p_PlaySoftIntData)
  7340. * a5    scratch
  7341. d3596 9
  7342. a3604 12
  7343.     pushm    a2/a3/a4/a6
  7344.     move.l    a1,a5
  7345.     movem.l    (a5)+,a0/a1/a2/a3/a4/a6
  7346.     jsr    (a3)                ;call Player Hook
  7347.     jsr    (a4)                ;call PreTimer
  7348.     bne    .exit
  7349.     movem.l    (a5),d0/a0/a1/a2/a3/a4/a5
  7350.     jsr    (a3)                ;call Mixer Hook
  7351.     push    a2
  7352. * convert and transfer buffer, using the table
  7353.     movem.l    (a4),a0/a2/a3/a4
  7354.     moveq    #0,d1
  7355. a3605 1
  7356.  REPT    2
  7357. d3607 43
  7358. a3649 4
  7359. ;left
  7360.  IFD    MC020
  7361.     move.w    (a1)+,d1            ;fetch 16 bit sample
  7362.     move.w    (a5,d1.l*2),d1
  7363. d3651 47
  7364. a3697 4
  7365.     moveq    #0,d1
  7366.     move.w    (a1)+,d1            ;fetch 16 bit sample
  7367.     add.w    d1,d1
  7368.     move.w    (a5,d1.l),d1
  7369. d3699 7
  7370. a3705 9
  7371.     move.b    d1,(a3)+            ;low byte
  7372.     lsr.w    #8,d1
  7373.     move.b    d1,(a2)+            ;high byte
  7374.     addq.l    #2,a1
  7375.  
  7376. ;right
  7377.  IFD    MC020
  7378.     move.w    (a1)+,d1            ;fetch 16 bit sample
  7379.     move.w    (a5,d1.l*2),d1
  7380. d3707 12
  7381. a3718 10
  7382.     moveq    #0,d1
  7383.     move.w    (a1)+,d1            ;fetch 16 bit sample
  7384.      add.w    d1,d1
  7385.      move.w    (a5,d1.l),d1
  7386.  ENDC
  7387.     move.b    d1,(a4)+            ;low byte
  7388.     lsr.w    #8,d1
  7389.     move.b    d1,(a0)+            ;high byte
  7390.     addq.l    #2,a1
  7391.  ENDR
  7392. d3721 14
  7393. a3734 5
  7394.     pop    a2
  7395. .exit
  7396.     jsr    (a6)                ;call PostTimer
  7397.     popm    a2/a3/a4/a6
  7398.     move.w    #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,custom+DMACON
  7399. a3735 1
  7400.  
  7401. @
  7402.